From be3cee14e6be88cb858134a97a05bcc97afb0048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl> Date: Sat, 20 Jun 2020 18:55:01 +0200 Subject: [PATCH] added satella.cassandra, v2.8.6 --- CHANGELOG.md | 1 + docs/cassandra.rst | 13 +++++++++++++ docs/index.rst | 1 + satella/__init__.py | 2 +- satella/cassandra/__init__.py | 24 ++++++++++++++++++++++++ setup.py | 3 ++- tests/test_cassandra.py | 25 +++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 docs/cassandra.rst create mode 100644 satella/cassandra/__init__.py create mode 100644 tests/test_cassandra.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 3628e62b..eb6b91c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,3 +2,4 @@ * added `time_us` * updated `stringify` to correctly handle None-cases +* added `satella.cassandra.parallel_for` diff --git a/docs/cassandra.rst b/docs/cassandra.rst new file mode 100644 index 00000000..0842a51c --- /dev/null +++ b/docs/cassandra.rst @@ -0,0 +1,13 @@ +**This module is available only if you have cassandra-driver installed** + +Cassandra +========= + +parallel_for +------------ + +If you have multiple async requests that would hit multiple nodes +and you would prefer to make use of `execute_async` and want to better +make use of them, here's the routine to help you out. + +.. autofunction:: satella.cassandra.parallel_for diff --git a/docs/index.rst b/docs/index.rst index 7e5d5ad8..4c0f60fc 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,6 +29,7 @@ Visit the project's page at GitHub_! time exceptions processes + cassandra Indices and tables diff --git a/satella/__init__.py b/satella/__init__.py index 0934f03c..7039ccb2 100644 --- a/satella/__init__.py +++ b/satella/__init__.py @@ -1 +1 @@ -__version__ = '2.8.6_a3' +__version__ = '2.8.6' diff --git a/satella/cassandra/__init__.py b/satella/cassandra/__init__.py new file mode 100644 index 00000000..f3d00937 --- /dev/null +++ b/satella/cassandra/__init__.py @@ -0,0 +1,24 @@ +import typing as tp +from collections import namedtuple + + +def parallel_for(cursor, query: str, arguments: tp.Iterable[tuple]) -> tp.Iterator[namedtuple]: + """ + Syntactic sugar for + + >>> futures = [] + >>> for args in arguments: + >>> futures.append(cur.execute_async(query, args)) + >>> for future in futures: + >>> yield future.result() + + :param cursor: the Cassandra cursor to use + :param query: base query + :param arguments: iterable yielding arguments to use in execute_async + """ + futures = [] + for args in arguments: + futures.append(cursor.execute_async(query, args)) + + for future in futures: + yield future.result() diff --git a/setup.py b/setup.py index ef8a18a6..dbf6e556 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ setup(keywords=['ha', 'high availability', 'scalable', 'scalability', 'server', extras_require={ 'HTTPJSONSource': ['requests'], 'YAMLSource': ['pyyaml'], - 'TOMLSource': ['toml'] + 'TOMLSource': ['toml'], + 'satella.cassandra': ['cassandra-driver'] } ) diff --git a/tests/test_cassandra.py b/tests/test_cassandra.py new file mode 100644 index 00000000..98bdf0b2 --- /dev/null +++ b/tests/test_cassandra.py @@ -0,0 +1,25 @@ +from satella.cassandra import parallel_for +import unittest + + +class TestCassandra(unittest.TestCase): + def test_parallel_for(self): + class Cursor: + def __init__(self): + self.execute_times_called = 0 + self.result_times_called = 0 + + def result(self): + self.result_times_called += 1 + return [] + + def execute_async(self, query, args): + self.execute_times_called += 1 + return self + + cur = Cursor() + for row in parallel_for(cur, 'SELECT * FROM table', [(1,), (2, ), (3, )]): + pass + + self.assertEqual(cur.execute_times_called, 3) + self.assertEqual(cur.result_times_called, 3) \ No newline at end of file -- GitLab