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/20bcc832 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/20bcc832 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/20bcc832 Branch: refs/heads/TINKERPOP-1458 Commit: 20bcc83268c7439db9e3efaf78cae66f17f8ecf0 Parents: be655e6 Author: davebshow <[email protected]> Authored: Wed Oct 5 18:00:27 2016 -0400 Committer: davebshow <[email protected]> Committed: Fri Oct 7 10:34:31 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/20bcc832/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/20bcc832/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__':
