ez-a-sync 0.24.33__tar.gz → 0.24.34__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/PKG-INFO +1 -1
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/queue.py +76 -50
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/PKG-INFO +1 -1
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.coverage +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/black.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/codeql.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/docs.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/mypy.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/pytest.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.github/workflows/release.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.gitignore +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/.sourcery.yaml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/LICENSE.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/MANIFEST.in +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/Makefile +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/README.md +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/TODO +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/ENVIRONMENT_VARIABLES.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/__init__.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/_smart.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/_smart.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/_typing.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_descriptor.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_flags.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_flags.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_flags.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_helpers.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_helpers.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_helpers.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_helpers.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_kwargs.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_kwargs.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_kwargs.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/_meta.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/abstract.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/abstract.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/abstract.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/base.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/base.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/base.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/config.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/decorator.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/flags.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/function.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/function.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/function.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/method.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/method.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/method.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/method.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/cache/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/cache/memory.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/limiter.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/manager.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/manager.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/manager.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/modifiers/semaphores.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/property.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/property.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/property.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/a_sync/singleton.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/aliases.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/as_completed.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/as_completed.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/as_completed.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/as_completed.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/create_task.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/create_task.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/create_task.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/create_task.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/gather.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/gather.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/asyncio/gather.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/exceptions.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/executor.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/future.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/iter.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/iter.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/iter.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/__init__.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_debug.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_debug.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_debug.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_debug.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_loggable.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_loggable.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_loggable.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/_loggable.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/__init__.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/counter.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/counter.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/counter.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/counter.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/event.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/event.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/event.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/event.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/prio_semaphore.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/prio_semaphore.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/prio_semaphore.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/prio_semaphore.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/semaphore.c +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/semaphore.pxd +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/semaphore.pyi +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/primitives/locks/semaphore.pyx +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/py.typed +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/sphinx/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/sphinx/ext.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/task.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/utils/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/a_sync/utils/iterators.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/Makefile +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/alabaster.css +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/basic.css +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/custom.css +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/doctools.js +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/documentation_options.js +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/file.png +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/language_data.js +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/minus.png +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/plus.png +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/pygments.css +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/searchtools.js +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/_build/html/_static/sphinx_highlight.js +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/conf.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/index.rst +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/docs/make.bat +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/SOURCES.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/dependency_links.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/not-zip-safe +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/requires.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/ez_a_sync.egg-info/top_level.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/pyproject.toml +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/requirements-dev.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/requirements.txt +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/setup.cfg +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/setup.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/__init__.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/modifiers/test_apply_semaphore.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_abstract.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_base.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_cache.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_decorator.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_limiter.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_meta.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_modified.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/a_sync/test_singleton.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/asyncio/test_as_completed.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/asyncio/test_create_task.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/asyncio/test_gather.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/conftest.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/executor.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/fixtures.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/primitives/test_counter.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/primitives/test_event.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/primitives/test_prio_semaphore.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/primitives/test_queue.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/primitives/test_semaphore.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/task/test_task.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/task/test_task_mapping_views.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/test_executor.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/test_future.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/test_helpers.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/test_iter.py +0 -0
- {ez_a_sync-0.24.33 → ez_a_sync-0.24.34}/tests/test_smart.py +0 -0
|
@@ -19,9 +19,11 @@ import heapq
|
|
|
19
19
|
import logging
|
|
20
20
|
import sys
|
|
21
21
|
import weakref
|
|
22
|
+
from asyncio import InvalidStateError, QueueEmpty, gather
|
|
22
23
|
|
|
23
24
|
import a_sync.asyncio
|
|
24
|
-
from a_sync import
|
|
25
|
+
from a_sync._smart import SmartFuture, create_future
|
|
26
|
+
from a_sync._smart import _Key as _SmartKey
|
|
25
27
|
from a_sync._typing import *
|
|
26
28
|
|
|
27
29
|
logger = logging.getLogger(__name__)
|
|
@@ -156,7 +158,7 @@ class Queue(_Queue[T]):
|
|
|
156
158
|
"""
|
|
157
159
|
try:
|
|
158
160
|
return self.get_all_nowait()
|
|
159
|
-
except
|
|
161
|
+
except QueueEmpty:
|
|
160
162
|
return [await self.get()]
|
|
161
163
|
|
|
162
164
|
def get_all_nowait(self) -> List[T]:
|
|
@@ -173,13 +175,16 @@ class Queue(_Queue[T]):
|
|
|
173
175
|
>>> tasks = queue.get_all_nowait()
|
|
174
176
|
>>> print(tasks)
|
|
175
177
|
"""
|
|
178
|
+
get_nowait = self.get_nowait
|
|
176
179
|
values: List[T] = []
|
|
180
|
+
append = values.append
|
|
181
|
+
|
|
177
182
|
while True:
|
|
178
183
|
try:
|
|
179
|
-
|
|
180
|
-
except
|
|
184
|
+
append(get_nowait())
|
|
185
|
+
except QueueEmpty as e:
|
|
181
186
|
if not values:
|
|
182
|
-
raise
|
|
187
|
+
raise QueueEmpty from e
|
|
183
188
|
return values
|
|
184
189
|
|
|
185
190
|
async def get_multi(self, i: int, can_return_less: bool = False) -> List[T]:
|
|
@@ -198,12 +203,16 @@ class Queue(_Queue[T]):
|
|
|
198
203
|
>>> print(tasks)
|
|
199
204
|
"""
|
|
200
205
|
_validate_args(i, can_return_less)
|
|
206
|
+
get_next = self.get
|
|
207
|
+
get_multi = self.get_multi_nowait
|
|
208
|
+
|
|
201
209
|
items = []
|
|
210
|
+
extend = items.extend
|
|
202
211
|
while len(items) < i and not can_return_less:
|
|
203
212
|
try:
|
|
204
|
-
|
|
205
|
-
except
|
|
206
|
-
items = [await
|
|
213
|
+
extend(get_multi(i - len(items), can_return_less=True))
|
|
214
|
+
except QueueEmpty:
|
|
215
|
+
items = [await get_next()]
|
|
207
216
|
return items
|
|
208
217
|
|
|
209
218
|
def get_multi_nowait(self, i: int, can_return_less: bool = False) -> List[T]:
|
|
@@ -222,17 +231,22 @@ class Queue(_Queue[T]):
|
|
|
222
231
|
>>> print(tasks)
|
|
223
232
|
"""
|
|
224
233
|
_validate_args(i, can_return_less)
|
|
234
|
+
|
|
235
|
+
get_nowait = self.get_nowait
|
|
236
|
+
|
|
225
237
|
items = []
|
|
238
|
+
append = items.append
|
|
226
239
|
for _ in range(i):
|
|
227
240
|
try:
|
|
228
|
-
|
|
229
|
-
except
|
|
241
|
+
append(get_nowait())
|
|
242
|
+
except QueueEmpty:
|
|
230
243
|
if items and can_return_less:
|
|
231
244
|
return items
|
|
232
245
|
# put these back in the queue since we didn't return them
|
|
246
|
+
put_nowait = self.put_nowait
|
|
233
247
|
for value in items:
|
|
234
|
-
|
|
235
|
-
raise
|
|
248
|
+
put_nowait(value)
|
|
249
|
+
raise QueueEmpty from None
|
|
236
250
|
return items
|
|
237
251
|
|
|
238
252
|
|
|
@@ -359,7 +373,8 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
|
|
|
359
373
|
context = {
|
|
360
374
|
"message": f"{self} was destroyed but has work pending!",
|
|
361
375
|
}
|
|
362
|
-
asyncio.
|
|
376
|
+
if loop := asyncio.events._get_running_loop():
|
|
377
|
+
loop.call_exception_handler(context)
|
|
363
378
|
|
|
364
379
|
@property
|
|
365
380
|
def name(self) -> str:
|
|
@@ -426,7 +441,7 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
|
|
|
426
441
|
|
|
427
442
|
def _create_future(self) -> "asyncio.Future[V]":
|
|
428
443
|
"""Creates a future for the task."""
|
|
429
|
-
return asyncio.
|
|
444
|
+
return asyncio.events._get_running_loop().create_future()
|
|
430
445
|
|
|
431
446
|
def _ensure_workers(self) -> None:
|
|
432
447
|
"""Ensures that the worker tasks are running."""
|
|
@@ -448,16 +463,16 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
|
|
|
448
463
|
def _workers(self) -> "asyncio.Task[NoReturn]":
|
|
449
464
|
"""Creates and manages the worker tasks for the queue."""
|
|
450
465
|
logger.debug("starting worker task for %s", self)
|
|
451
|
-
workers =
|
|
466
|
+
workers = tuple(
|
|
452
467
|
a_sync.asyncio.create_task(
|
|
453
468
|
coro=self._worker_coro(),
|
|
454
469
|
name=f"{self.name} [Task-{i}]",
|
|
455
470
|
log_destroy_pending=False,
|
|
456
471
|
)
|
|
457
472
|
for i in range(self.num_workers)
|
|
458
|
-
|
|
473
|
+
)
|
|
459
474
|
task = a_sync.asyncio.create_task(
|
|
460
|
-
|
|
475
|
+
gather(*workers),
|
|
461
476
|
name=f"{self.name} worker main Task",
|
|
462
477
|
log_destroy_pending=False,
|
|
463
478
|
)
|
|
@@ -468,49 +483,53 @@ class ProcessingQueue(_Queue[Tuple[P, "asyncio.Future[V]"]], Generic[P, V]):
|
|
|
468
483
|
"""
|
|
469
484
|
The coroutine executed by worker tasks to process the queue.
|
|
470
485
|
"""
|
|
486
|
+
get_next_job = self.get
|
|
487
|
+
func = self.func
|
|
488
|
+
task_done = self.task_done
|
|
489
|
+
|
|
471
490
|
args: P.args
|
|
472
491
|
kwargs: P.kwargs
|
|
473
492
|
if self._no_futs:
|
|
474
493
|
while True:
|
|
475
494
|
try:
|
|
476
|
-
args, kwargs = await
|
|
477
|
-
await
|
|
495
|
+
args, kwargs = await get_next_job()
|
|
496
|
+
await func(*args, **kwargs)
|
|
478
497
|
except Exception as e:
|
|
479
498
|
logger.error("%s in worker for %s!", type(e).__name__, self)
|
|
480
499
|
logger.exception(e)
|
|
481
|
-
|
|
500
|
+
task_done()
|
|
482
501
|
else:
|
|
483
502
|
fut: asyncio.Future[V]
|
|
484
503
|
while True:
|
|
485
504
|
try:
|
|
486
|
-
args, kwargs, fut = await
|
|
505
|
+
args, kwargs, fut = await get_next_job()
|
|
487
506
|
try:
|
|
488
507
|
if fut is None:
|
|
489
508
|
# the weakref was already cleaned up, we don't need to process this item
|
|
490
|
-
|
|
509
|
+
task_done()
|
|
491
510
|
continue
|
|
492
|
-
result = await
|
|
511
|
+
result = await func(*args, **kwargs)
|
|
493
512
|
fut.set_result(result)
|
|
494
|
-
except
|
|
513
|
+
except InvalidStateError:
|
|
495
514
|
logger.error(
|
|
496
515
|
"cannot set result for %s %s: %s",
|
|
497
|
-
|
|
516
|
+
func.__name__,
|
|
498
517
|
fut,
|
|
499
518
|
result,
|
|
500
519
|
)
|
|
501
520
|
except Exception as e:
|
|
502
521
|
try:
|
|
503
522
|
fut.set_exception(e)
|
|
504
|
-
except
|
|
523
|
+
except InvalidStateError:
|
|
505
524
|
logger.error(
|
|
506
525
|
"cannot set exception for %s %s: %s",
|
|
507
|
-
|
|
526
|
+
func.__name__,
|
|
508
527
|
fut,
|
|
509
528
|
e,
|
|
510
529
|
)
|
|
511
|
-
|
|
530
|
+
task_done()
|
|
512
531
|
except Exception as e:
|
|
513
|
-
logger.error("%s for %s is broken!!!", type(self).__name__,
|
|
532
|
+
logger.error("%s for %s is broken!!!", type(self).__name__, func)
|
|
514
533
|
logger.exception(e)
|
|
515
534
|
raise
|
|
516
535
|
|
|
@@ -540,10 +559,10 @@ def _validate_args(i: int, can_return_less: bool) -> None:
|
|
|
540
559
|
|
|
541
560
|
class _SmartFutureRef(weakref.ref, Generic[T]):
|
|
542
561
|
"""
|
|
543
|
-
Weak reference for :class:`~
|
|
562
|
+
Weak reference for :class:`~SmartFuture` objects used in priority queues.
|
|
544
563
|
|
|
545
564
|
See Also:
|
|
546
|
-
:class:`~
|
|
565
|
+
:class:`~SmartFuture`
|
|
547
566
|
"""
|
|
548
567
|
|
|
549
568
|
def __lt__(self, other: "_SmartFutureRef[T]") -> bool:
|
|
@@ -568,7 +587,9 @@ class _SmartFutureRef(weakref.ref, Generic[T]):
|
|
|
568
587
|
if strong_self is None:
|
|
569
588
|
return True
|
|
570
589
|
strong_other = other()
|
|
571
|
-
|
|
590
|
+
if strong_other is None:
|
|
591
|
+
return False
|
|
592
|
+
return strong_self < strong_other
|
|
572
593
|
|
|
573
594
|
|
|
574
595
|
class _PriorityQueueMixin(Generic[T]):
|
|
@@ -711,7 +732,7 @@ class _VariablePriorityQueueMixin(_PriorityQueueMixin[T]):
|
|
|
711
732
|
# `self._queue` will always be in proper order for next call to `self._get`.
|
|
712
733
|
return heappop(self._queue)
|
|
713
734
|
|
|
714
|
-
def _get_key(self, *args, **kwargs) ->
|
|
735
|
+
def _get_key(self, *args, **kwargs) -> _SmartKey:
|
|
715
736
|
"""
|
|
716
737
|
Generates a unique key for task identification based on arguments.
|
|
717
738
|
|
|
@@ -771,7 +792,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
|
|
|
771
792
|
_no_futs = False
|
|
772
793
|
"""Whether smart futures are used."""
|
|
773
794
|
|
|
774
|
-
_futs: "weakref.WeakValueDictionary[
|
|
795
|
+
_futs: "weakref.WeakValueDictionary[_SmartKey[T], SmartFuture[T]]"
|
|
775
796
|
"""
|
|
776
797
|
Weak reference dictionary for managing smart futures.
|
|
777
798
|
"""
|
|
@@ -800,7 +821,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
|
|
|
800
821
|
super().__init__(func, num_workers, return_data=True, name=name, loop=loop)
|
|
801
822
|
self._futs = weakref.WeakValueDictionary()
|
|
802
823
|
|
|
803
|
-
async def put(self, *args: P.args, **kwargs: P.kwargs) ->
|
|
824
|
+
async def put(self, *args: P.args, **kwargs: P.kwargs) -> SmartFuture[V]:
|
|
804
825
|
"""
|
|
805
826
|
Asynchronously adds a task with smart future handling to the queue.
|
|
806
827
|
|
|
@@ -824,7 +845,7 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
|
|
|
824
845
|
await Queue.put(self, (_SmartFutureRef(fut), args, kwargs))
|
|
825
846
|
return fut
|
|
826
847
|
|
|
827
|
-
def put_nowait(self, *args: P.args, **kwargs: P.kwargs) ->
|
|
848
|
+
def put_nowait(self, *args: P.args, **kwargs: P.kwargs) -> SmartFuture[V]:
|
|
828
849
|
"""
|
|
829
850
|
Immediately adds a task with smart future handling to the queue without waiting.
|
|
830
851
|
|
|
@@ -848,9 +869,9 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
|
|
|
848
869
|
Queue.put_nowait(self, (_SmartFutureRef(fut), args, kwargs))
|
|
849
870
|
return fut
|
|
850
871
|
|
|
851
|
-
def _create_future(self, key:
|
|
872
|
+
def _create_future(self, key: _SmartKey) -> "asyncio.Future[V]":
|
|
852
873
|
"""Creates a smart future for the task."""
|
|
853
|
-
return
|
|
874
|
+
return create_future(queue=self, key=key, loop=self._loop)
|
|
854
875
|
|
|
855
876
|
def _get(self):
|
|
856
877
|
"""
|
|
@@ -878,40 +899,45 @@ class SmartProcessingQueue(_VariablePriorityQueueMixin[T], ProcessingQueue[Conca
|
|
|
878
899
|
Example:
|
|
879
900
|
>>> await queue.__worker_coro()
|
|
880
901
|
"""
|
|
902
|
+
get_next_job = self.get
|
|
903
|
+
func = self.func
|
|
904
|
+
task_done = self.task_done
|
|
905
|
+
log_debug = logger.debug
|
|
906
|
+
|
|
881
907
|
args: P.args
|
|
882
908
|
kwargs: P.kwargs
|
|
883
|
-
fut:
|
|
909
|
+
fut: SmartFuture[V]
|
|
884
910
|
while True:
|
|
885
911
|
try:
|
|
886
912
|
try:
|
|
887
|
-
args, kwargs, fut = await
|
|
913
|
+
args, kwargs, fut = await get_next_job()
|
|
888
914
|
if fut is None:
|
|
889
915
|
# the weakref was already cleaned up, we don't need to process this item
|
|
890
|
-
|
|
916
|
+
task_done()
|
|
891
917
|
continue
|
|
892
|
-
|
|
893
|
-
result = await
|
|
918
|
+
log_debug("processing %s", fut)
|
|
919
|
+
result = await func(*args, **kwargs)
|
|
894
920
|
fut.set_result(result)
|
|
895
|
-
except
|
|
921
|
+
except InvalidStateError:
|
|
896
922
|
logger.error(
|
|
897
923
|
"cannot set result for %s %s: %s",
|
|
898
|
-
|
|
924
|
+
func.__name__,
|
|
899
925
|
fut,
|
|
900
926
|
result,
|
|
901
927
|
)
|
|
902
928
|
except Exception as e:
|
|
903
|
-
|
|
929
|
+
log_debug("%s: %s", type(e).__name__, e)
|
|
904
930
|
try:
|
|
905
931
|
fut.set_exception(e)
|
|
906
|
-
except
|
|
932
|
+
except InvalidStateError:
|
|
907
933
|
logger.error(
|
|
908
934
|
"cannot set exception for %s %s: %s",
|
|
909
|
-
|
|
935
|
+
func.__name__,
|
|
910
936
|
fut,
|
|
911
937
|
e,
|
|
912
938
|
)
|
|
913
|
-
|
|
939
|
+
task_done()
|
|
914
940
|
except Exception as e:
|
|
915
|
-
logger.error("%s for %s is broken!!!", type(self).__name__,
|
|
941
|
+
logger.error("%s for %s is broken!!!", type(self).__name__, func)
|
|
916
942
|
logger.exception(e)
|
|
917
943
|
raise
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|