From 9a1912f6f9389e111e21786a42941e224c4a3841 Mon Sep 17 00:00:00 2001 From: davebshow <davebshow@gmail.com> Date: Wed, 13 May 2015 13:39:23 -0400 Subject: [PATCH] getting ready for release --- README.md | 2 +- aiogremlin/__init__.py | 6 ++++-- aiogremlin/client.py | 20 +++++++++--------- benchmarks/__init__.py | 0 benchmarks/client_bench.py | 42 ++++++++++++++++++++++++++++++++++++++ changes.txt | 1 + setup.py | 2 +- 7 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 benchmarks/__init__.py create mode 100644 benchmarks/client_bench.py diff --git a/README.md b/README.md index a5c1922..f0aff85 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# aiogremlin 0.0.4 [(gizmo grew up)](https://pypi.python.org/pypi/gizmo/0.1.12) +# aiogremlin 0.0.5 [(gizmo grew up)](https://pypi.python.org/pypi/gizmo/0.1.12) `aiogremlin` is a **Python 3** driver for the the [Tinkerpop 3 Gremlin Server](http://www.tinkerpop.com/docs/3.0.0.M7/#gremlin-server). This module is built on [Asyncio](https://docs.python.org/3/library/asyncio.html). By default it uses the [aiohttp](http://aiohttp.readthedocs.org/en/v0.15.3/index.html) websocket client , but it is easy to plug in a different implementation. `aiogremlin` is currently in **alpha** mode, but all major functionality has test coverage. diff --git a/aiogremlin/__init__.py b/aiogremlin/__init__.py index e666a2b..2a06010 100644 --- a/aiogremlin/__init__.py +++ b/aiogremlin/__init__.py @@ -1,6 +1,8 @@ from .abc import AbstractFactory, AbstractConnection from .connection import (WebsocketPool, AiohttpFactory, BaseFactory, BaseConnection) -from .client import GremlinClient, create_client +from .client import (create_client, GremlinClient, GremlinResponse, + GremlinResponseStream) from .exceptions import RequestError, GremlinServerError, SocketClientError -__version__ = "0.0.4dev" +from .protocol import GremlinWriter +__version__ = "0.0.5" diff --git a/aiogremlin/client.py b/aiogremlin/client.py index 1025ff0..224a0f2 100644 --- a/aiogremlin/client.py +++ b/aiogremlin/client.py @@ -109,9 +109,7 @@ class GremlinClient: connection = yield from self.pool.connect(self.uri, loop=self.loop) writer = GremlinWriter(connection) connection = yield from writer.write(message, binary=binary) - queue = connection.parser.set_parser(gremlin_response_parser, - output=aiohttp.DataQueue(loop=self._loop)) - return GremlinResponse(connection, queue, loop=self._loop) + return GremlinResponse(connection, loop=self._loop) @asyncio.coroutine def execute(self, gremlin, bindings=None, lang=None, @@ -128,9 +126,9 @@ class GremlinClient: class GremlinResponse: - def __init__(self, conn, queue, loop=None): + def __init__(self, conn, loop=None): self._loop = loop or asyncio.get_event_loop() - self._stream = GremlinResponseStream(conn, queue, loop=self._loop) + self._stream = GremlinResponseStream(conn, loop=self._loop) @property def stream(self): @@ -155,23 +153,25 @@ class GremlinResponse: class GremlinResponseStream: - def __init__(self, conn, queue, loop=None): + def __init__(self, conn, loop=None): self._conn = conn - self._queue = queue self._loop = loop or asyncio.get_event_loop() + data_stream = aiohttp.DataQueue(loop=self._loop) + self._stream = self._conn.parser.set_parser(gremlin_response_parser, + output=data_stream) @asyncio.coroutine def read(self): # For 3.0.0.M9 - # if self._queue.at_eof(): + # if self._stream.at_eof(): # self._conn.feed_pool() # message = None # else: # This will be different 3.0.0.M9 yield from self._conn._receive() - if self._queue.is_eof(): + if self._stream.is_eof(): self._conn.feed_pool() message = None else: - message = yield from self._queue.read() + message = yield from self._stream.read() return message diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/benchmarks/client_bench.py b/benchmarks/client_bench.py new file mode 100644 index 0000000..7fb8843 --- /dev/null +++ b/benchmarks/client_bench.py @@ -0,0 +1,42 @@ +import asyncio +import collections + +from aiogremlin import GremlinClient + + +@asyncio.coroutine +def attack(loop): + + client = GremlinClient(loop=loop, poolsize=1000) + execute = client.execute + + out_times = collections.deque() + processed_count = 0 + + @asyncio.coroutine + def do_bomb(): + nonlocal processed_count + try: + t1 = loop.time() + resp = yield from execute("1 + 1") + assert resp[0].status_code == 200, resp[0].status_code + t2 = loop.time() + out_times.append(t2 - t1) + processed_count += 1 + except Exception: + print("an exception occurred {}".format(resp[0].status_code)) + + bombers = [] + for i in range(10000): + bomber = asyncio.async(do_bomb()) + bombers.append(bomber) + + t1 = loop.time() + yield from asyncio.gather(*bombers, loop=loop) + t2 = loop.time() + rps = processed_count / (t2 - t1) + print("Benchmark complete: {} rps".format(rps)) + +if __name__ == "__main__": + loop = asyncio.get_event_loop() + loop.run_until_complete(attack(loop)) diff --git a/changes.txt b/changes.txt index 2fbf42b..4f67059 100644 --- a/changes.txt +++ b/changes.txt @@ -2,3 +2,4 @@ 0.0.2 - 5/1/2015: Added an init_pool method and a create_client constructor. 0.0.3 - 5/2/2015: Using ujson for serialization. 0.0.4 - 5/12/2015: Added support for sessions. +0.0.5 - 5/13/2015: Using EofStream terminator technique to prepare for 3.0.0.M9 diff --git a/setup.py b/setup.py index 01a7bd9..3d9b70a 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup setup( name="aiogremlin", - version="0.0.4", + version="0.0.5", url="", license="MIT", author="davebshow", -- GitLab