Index: dashboard/dashboard/graph_revisions.py |
diff --git a/dashboard/dashboard/graph_revisions.py b/dashboard/dashboard/graph_revisions.py |
index 708803dbd117eb62806557ef41a17a03642ba174..b9b792de60794dbff61f9995813d32be91ef6b95 100644 |
--- a/dashboard/dashboard/graph_revisions.py |
+++ b/dashboard/dashboard/graph_revisions.py |
@@ -17,6 +17,8 @@ long time. This module also provides a function for updating the cache. |
import bisect |
import json |
+from google.appengine.ext import ndb |
+ |
from dashboard.common import datastore_hooks |
from dashboard.common import namespaced_stored_object |
from dashboard.common import request_handler |
@@ -45,6 +47,7 @@ class GraphRevisionsHandler(request_handler.RequestHandler): |
self.response.out.write(json.dumps(rows)) |
+@ndb.synctasklet |
def SetCache(test_path, rows): |
"""Sets the saved graph revisions data for a test. |
@@ -52,15 +55,23 @@ def SetCache(test_path, rows): |
test_path: A test path string. |
rows: A list of [revision, value, timestamp] triplets. |
""" |
+ yield SetCacheAsync(test_path, rows) |
+ |
+ |
+@ndb.tasklet |
+def SetCacheAsync(test_path, rows): |
# This first set generally only sets the internal-only cache. |
- namespaced_stored_object.Set(_CACHE_KEY % test_path, rows) |
+ futures = [namespaced_stored_object.SetAsync(_CACHE_KEY % test_path, rows)] |
# If this is an internal_only query for externally available data, |
# set the cache for that too. |
if datastore_hooks.IsUnalteredQueryPermitted(): |
test = utils.TestKey(test_path).get() |
if test and not test.internal_only: |
- namespaced_stored_object.SetExternal(_CACHE_KEY % test_path, rows) |
+ futures.append( |
+ namespaced_stored_object.SetExternalAsync( |
+ _CACHE_KEY % test_path, rows)) |
+ yield futures |
def DeleteCache(test_path): |
@@ -104,6 +115,7 @@ def _MakeTriplet(row): |
return [row.revision, row.value, timestamp] |
+@ndb.synctasklet |
def AddRowsToCache(row_entities): |
"""Adds a list of rows to the cache, in revision order. |
@@ -112,6 +124,18 @@ def AddRowsToCache(row_entities): |
Args: |
row_entities: List of Row entities. |
""" |
+ test_key_to_futures = {} |
+ for row in row_entities: |
+ test_key = row.parent_test |
+ if test_key in test_key_to_futures: |
+ continue |
+ |
+ test_path = utils.TestPath(test_key) |
+ test_key_to_futures[test_key] = namespaced_stored_object.GetAsync( |
+ _CACHE_KEY % test_path) |
+ |
+ yield test_key_to_futures.values() |
+ |
test_key_to_rows = {} |
for row in row_entities: |
test_key = row.parent_test |
@@ -119,7 +143,8 @@ def AddRowsToCache(row_entities): |
graph_rows = test_key_to_rows[test_key] |
else: |
test_path = utils.TestPath(test_key) |
- graph_rows = namespaced_stored_object.Get(_CACHE_KEY % test_path) |
+ graph_rows_future = test_key_to_futures.get(test_key) |
+ graph_rows = graph_rows_future.get_result() |
if not graph_rows: |
# We only want to update caches for tests that people have looked at. |
continue |
@@ -132,6 +157,8 @@ def AddRowsToCache(row_entities): |
return # Already in cache. |
graph_rows.insert(index, _MakeTriplet(row)) |
+ futures = [] |
for test_key in test_key_to_rows: |
graph_rows = test_key_to_rows[test_key] |
- SetCache(utils.TestPath(test_key), graph_rows) |
+ futures.append(SetCacheAsync(utils.TestPath(test_key), graph_rows)) |
+ yield futures |