updated driver to cache side effects locally
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f3baae8b Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f3baae8b Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f3baae8b Branch: refs/heads/TINKERPOP-1458 Commit: f3baae8ba2415191e700c3842f983001096168e5 Parents: fd2d6eb Author: davebshow <davebs...@gmail.com> Authored: Wed Oct 5 18:00:27 2016 -0400 Committer: davebshow <davebs...@gmail.com> Committed: Wed Oct 5 18:00:27 2016 -0400 ---------------------------------------------------------------------- .../gremlin_python/driver/remote_connection.py | 26 ++++++++++--- .../driver/test_driver_remote_connection.py | 39 +++++++++++++++++--- 2 files changed, 54 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3baae8b/gremlin-python/src/main/jython/gremlin_python/driver/remote_connection.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/gremlin_python/driver/remote_connection.py b/gremlin-python/src/main/jython/gremlin_python/driver/remote_connection.py index 3e7293f..46fb760 100644 --- a/gremlin-python/src/main/jython/gremlin_python/driver/remote_connection.py +++ b/gremlin-python/src/main/jython/gremlin_python/driver/remote_connection.py @@ -58,18 +58,32 @@ class RemoteTraversal(Traversal): class RemoteTraversalSideEffects(TraversalSideEffects): def __init__(self, keys_lambda, value_lambda, close_lambda): - self.keys_lambda = keys_lambda - self.value_lambda = value_lambda - self.close_lambda = close_lambda + self._keys_lambda = keys_lambda + self._value_lambda = value_lambda + self._close_lambda = close_lambda + self._keys = set() + self._side_effects = {} + self._closed = False def keys(self): - return self.keys_lambda() + if not self._closed: + self._keys = self._keys_lambda() + return self._keys def get(self, key): - return self.value_lambda(key) + if not self._side_effects.get(key): + if not self._closed: + results = self._value_lambda(key) + self._side_effects[key] = results + self._keys.add(key) + else: + return None + return self._side_effects[key] def close(self): - return self.close_lambda() + results = self._close_lambda() + self._closed = True + return results class RemoteStrategy(TraversalStrategy): http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f3baae8b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py ---------------------------------------------------------------------- diff --git a/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py index d96d35d..d3163d3 100644 --- a/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py +++ b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py @@ -106,6 +106,7 @@ class TestDriverRemoteConnection(TestCase): assert 3 == n["lop"] assert 1 == n["ripple"] + t = g.withSideEffect('m',32).V().map(lambda: "x: x.sideEffects('m')") results = t.toSet() assert 1 == len(results) @@ -117,11 +118,39 @@ class TestDriverRemoteConnection(TestCase): raise Exception("Accessing a non-existent key should throw an error") except KeyError: pass - result = t.side_effects.close() - assert not result - with pytest.raises(KeyError): - x = t.side_effects['m'] - connection.close() + + def test_side_effect_close(self): + connection = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g') + g = Graph().traversal().withRemote(connection) + t = g.V().aggregate('a').aggregate('b') + t.toList() + + # The 'a' key should return some side effects + results = t.side_effects.get('a') + assert results + + # Close result is None + results = t.side_effects.close() + assert not results + + # Shouldn't get any new info from server + # 'b' isn't in local cache + results = t.side_effects.get('b') + assert not results + + # But 'a' should still be cached locally + results = t.side_effects.get('a') + assert results + + # 'a' should have been added to local keys cache, but not 'b' + results = t.side_effects.keys() + assert len(results) == 1 + a, = results + assert a == 'a' + + # Try to get 'b' directly from server, should throw error + with pytest.raises(Exception): + t.side_effects.value_lambda('b') if __name__ == '__main__':