tasktiger 0.19__tar.gz → 0.19.2__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.
Files changed (55) hide show
  1. {tasktiger-0.19 → tasktiger-0.19.2}/PKG-INFO +30 -9
  2. tasktiger-0.19/tasktiger.egg-info/PKG-INFO → tasktiger-0.19.2/README.rst +26 -28
  3. {tasktiger-0.19 → tasktiger-0.19.2}/setup.py +4 -3
  4. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/executor.py +58 -13
  5. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/worker.py +2 -0
  6. tasktiger-0.19/README.rst → tasktiger-0.19.2/tasktiger.egg-info/PKG-INFO +49 -6
  7. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_workers.py +59 -2
  8. {tasktiger-0.19 → tasktiger-0.19.2}/tests/utils.py +4 -5
  9. {tasktiger-0.19 → tasktiger-0.19.2}/LICENSE +0 -0
  10. {tasktiger-0.19 → tasktiger-0.19.2}/MANIFEST.in +0 -0
  11. {tasktiger-0.19 → tasktiger-0.19.2}/pyproject.toml +0 -0
  12. {tasktiger-0.19 → tasktiger-0.19.2}/setup.cfg +0 -0
  13. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/__init__.py +0 -0
  14. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/_internal.py +0 -0
  15. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/exceptions.py +0 -0
  16. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/flask_script.py +0 -0
  17. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/logging.py +0 -0
  18. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/lua/move_task.lua +0 -0
  19. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/lua/semaphore.lua +0 -0
  20. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/migrations.py +0 -0
  21. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/redis_scripts.py +0 -0
  22. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/redis_semaphore.py +0 -0
  23. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/retry.py +0 -0
  24. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/rollbar.py +0 -0
  25. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/runner.py +0 -0
  26. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/schedule.py +0 -0
  27. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/stats.py +0 -0
  28. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/task.py +0 -0
  29. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/tasktiger.py +0 -0
  30. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/test_helpers.py +0 -0
  31. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/timeouts.py +0 -0
  32. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/types.py +0 -0
  33. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger/utils.py +0 -0
  34. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger.egg-info/SOURCES.txt +0 -0
  35. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger.egg-info/dependency_links.txt +0 -0
  36. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger.egg-info/entry_points.txt +0 -0
  37. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger.egg-info/requires.txt +0 -0
  38. {tasktiger-0.19 → tasktiger-0.19.2}/tasktiger.egg-info/top_level.txt +0 -0
  39. {tasktiger-0.19 → tasktiger-0.19.2}/tests/__init__.py +0 -0
  40. {tasktiger-0.19 → tasktiger-0.19.2}/tests/config.py +0 -0
  41. {tasktiger-0.19 → tasktiger-0.19.2}/tests/conftest.py +0 -0
  42. {tasktiger-0.19 → tasktiger-0.19.2}/tests/tasks.py +0 -0
  43. {tasktiger-0.19 → tasktiger-0.19.2}/tests/tasks_periodic.py +0 -0
  44. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_base.py +0 -0
  45. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_context_manager.py +0 -0
  46. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_lazy_init.py +0 -0
  47. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_logging.py +0 -0
  48. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_migrations.py +0 -0
  49. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_periodic.py +0 -0
  50. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_queue_size.py +0 -0
  51. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_redis_scripts.py +0 -0
  52. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_semaphore.py +0 -0
  53. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_stats.py +0 -0
  54. {tasktiger-0.19 → tasktiger-0.19.2}/tests/test_task.py +0 -0
  55. {tasktiger-0.19 → tasktiger-0.19.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tasktiger
3
- Version: 0.19
3
+ Version: 0.19.2
4
4
  Summary: Python task queue
5
5
  Home-page: http://github.com/closeio/tasktiger
6
6
  License: MIT
@@ -12,9 +12,10 @@ Classifier: Operating System :: POSIX :: Linux
12
12
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.6
16
- Classifier: Programming Language :: Python :: 3.7
17
15
  Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
18
19
  License-File: LICENSE
19
20
  Requires-Dist: click
20
21
  Requires-Dist: redis<5,>=3.3.0
@@ -40,13 +41,21 @@ TaskTiger
40
41
  Features
41
42
  --------
42
43
 
43
- - Per-task fork
44
+ - Per-task fork or synchronous worker
44
45
 
45
- TaskTiger forks a subprocess for each task, This comes with several benefits:
46
- Memory leaks caused by tasks are avoided since the subprocess is terminated
47
- when the task is finished. A hard time limit can be set for each task, after
48
- which the task is killed if it hasn't completed. To ensure performance, any
49
- necessary Python modules can be preloaded in the parent process.
46
+ By default, TaskTiger forks a subprocess for each task, This comes with
47
+ several benefits: Memory leaks caused by tasks are avoided since the
48
+ subprocess is terminated when the task is finished. A hard time limit can be
49
+ set for each task, after which the task is killed if it hasn't completed. To
50
+ ensure performance, any necessary Python modules can be preloaded in the
51
+ parent process.
52
+
53
+ TaskTiger also supports synchronous workers, which allows for better
54
+ performance due to no forking overhead, and tasks have the ability to reuse
55
+ network connections. To prevent memory leaks from accumulating, workers can
56
+ be set to shutdown after a certain amount of time, at which point a
57
+ supervisor can restart them. Workers also automatically exit on on hard
58
+ timeouts to prevent an inconsistent process state.
50
59
 
51
60
  - Unique queues
52
61
 
@@ -574,6 +583,18 @@ Workers support the following options:
574
583
 
575
584
  Store tracebacks with execution history (config defaults to ``True``).
576
585
 
586
+ - ``--executor``
587
+
588
+ Can be ``fork`` (default) or ``sync``. Whether to execute tasks in a separate
589
+ process via fork, or execute them synchronously in the same proces. See
590
+ "Features" section for the benefits of either approach.
591
+
592
+ - ``--exit-after``
593
+
594
+ Exit the worker after the time in minutes has elapsed. This is mainly useful
595
+ with the synchronous executor to prevent memory leaks from accumulating.
596
+
597
+
577
598
  In some cases it is convenient to have a custom TaskTiger launch script. For
578
599
  example, your application may have a ``manage.py`` command that sets up the
579
600
  environment and you may want to launch TaskTiger workers using that script. To
@@ -1,25 +1,3 @@
1
- Metadata-Version: 2.1
2
- Name: tasktiger
3
- Version: 0.19
4
- Summary: Python task queue
5
- Home-page: http://github.com/closeio/tasktiger
6
- License: MIT
7
- Classifier: Intended Audience :: Developers
8
- Classifier: License :: OSI Approved :: MIT License
9
- Classifier: Operating System :: MacOS :: MacOS X
10
- Classifier: Operating System :: POSIX
11
- Classifier: Operating System :: POSIX :: Linux
12
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
- Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.6
16
- Classifier: Programming Language :: Python :: 3.7
17
- Classifier: Programming Language :: Python :: 3.8
18
- License-File: LICENSE
19
- Requires-Dist: click
20
- Requires-Dist: redis<5,>=3.3.0
21
- Requires-Dist: structlog
22
-
23
1
  =========
24
2
  TaskTiger
25
3
  =========
@@ -40,13 +18,21 @@ TaskTiger
40
18
  Features
41
19
  --------
42
20
 
43
- - Per-task fork
21
+ - Per-task fork or synchronous worker
22
+
23
+ By default, TaskTiger forks a subprocess for each task, This comes with
24
+ several benefits: Memory leaks caused by tasks are avoided since the
25
+ subprocess is terminated when the task is finished. A hard time limit can be
26
+ set for each task, after which the task is killed if it hasn't completed. To
27
+ ensure performance, any necessary Python modules can be preloaded in the
28
+ parent process.
44
29
 
45
- TaskTiger forks a subprocess for each task, This comes with several benefits:
46
- Memory leaks caused by tasks are avoided since the subprocess is terminated
47
- when the task is finished. A hard time limit can be set for each task, after
48
- which the task is killed if it hasn't completed. To ensure performance, any
49
- necessary Python modules can be preloaded in the parent process.
30
+ TaskTiger also supports synchronous workers, which allows for better
31
+ performance due to no forking overhead, and tasks have the ability to reuse
32
+ network connections. To prevent memory leaks from accumulating, workers can
33
+ be set to shutdown after a certain amount of time, at which point a
34
+ supervisor can restart them. Workers also automatically exit on on hard
35
+ timeouts to prevent an inconsistent process state.
50
36
 
51
37
  - Unique queues
52
38
 
@@ -574,6 +560,18 @@ Workers support the following options:
574
560
 
575
561
  Store tracebacks with execution history (config defaults to ``True``).
576
562
 
563
+ - ``--executor``
564
+
565
+ Can be ``fork`` (default) or ``sync``. Whether to execute tasks in a separate
566
+ process via fork, or execute them synchronously in the same proces. See
567
+ "Features" section for the benefits of either approach.
568
+
569
+ - ``--exit-after``
570
+
571
+ Exit the worker after the time in minutes has elapsed. This is mainly useful
572
+ with the synchronous executor to prevent memory leaks from accumulating.
573
+
574
+
577
575
  In some cases it is convenient to have a custom TaskTiger launch script. For
578
576
  example, your application may have a ``manage.py`` command that sets up the
579
577
  environment and you may want to launch TaskTiger workers using that script. To
@@ -9,7 +9,7 @@ tests_require = install_requires + ["freezefrog", "pytest", "psutil"]
9
9
 
10
10
  setup(
11
11
  name="tasktiger",
12
- version="0.19",
12
+ version="0.19.2",
13
13
  url="http://github.com/closeio/tasktiger",
14
14
  license="MIT",
15
15
  description="Python task queue",
@@ -26,9 +26,10 @@ setup(
26
26
  "Topic :: Software Development :: Libraries :: Python Modules",
27
27
  "Programming Language :: Python",
28
28
  "Programming Language :: Python :: 3",
29
- "Programming Language :: Python :: 3.6",
30
- "Programming Language :: Python :: 3.7",
31
29
  "Programming Language :: Python :: 3.8",
30
+ "Programming Language :: Python :: 3.9",
31
+ "Programming Language :: Python :: 3.10",
32
+ "Programming Language :: Python :: 3.11",
32
33
  ],
33
34
  packages=["tasktiger"],
34
35
  package_data={"tasktiger": ["lua/*.lua"]},
@@ -63,6 +63,25 @@ class Executor:
63
63
  self.connection = worker.connection
64
64
  self.config = worker.config
65
65
 
66
+ def heartbeat(
67
+ self,
68
+ queue: str,
69
+ task_ids: Collection[str],
70
+ log: BoundLogger,
71
+ locks: Collection[Lock],
72
+ queue_lock: Optional[Semaphore],
73
+ ) -> None:
74
+ self.worker.heartbeat(queue, task_ids)
75
+ for lock in locks:
76
+ try:
77
+ lock.reacquire()
78
+ except LockError:
79
+ log.warning("could not reacquire lock", lock=lock.name)
80
+ if queue_lock:
81
+ acquired, current_locks = queue_lock.renew()
82
+ if not acquired:
83
+ log.debug("queue lock renew failure")
84
+
66
85
  def execute(
67
86
  self,
68
87
  queue: str,
@@ -351,18 +370,7 @@ class ForkExecutor(Executor):
351
370
  break
352
371
 
353
372
  try:
354
- self.worker.heartbeat(queue, all_task_ids)
355
- for lock in locks:
356
- try:
357
- lock.reacquire()
358
- except LockError:
359
- log.warning(
360
- "could not reacquire lock", lock=lock.name
361
- )
362
- if queue_lock:
363
- acquired, current_locks = queue_lock.renew()
364
- if not acquired:
365
- log.debug("queue lock renew failure")
373
+ self.heartbeat(queue, all_task_ids, log, locks, queue_lock)
366
374
  except OSError as e:
367
375
  # EINTR happens if the task completed. Since we're just
368
376
  # renewing locks/heartbeat it's okay if we get interrupted.
@@ -386,6 +394,21 @@ class SyncExecutor(Executor):
386
394
 
387
395
  exit_worker_on_job_timeout = True
388
396
 
397
+ def _periodic_heartbeat(
398
+ self,
399
+ queue: str,
400
+ task_ids: Collection[str],
401
+ log: BoundLogger,
402
+ locks: Collection[Lock],
403
+ queue_lock: Optional[Semaphore],
404
+ stop_event: threading.Event,
405
+ ) -> None:
406
+ while not stop_event.wait(self.config["ACTIVE_TASK_UPDATE_TIMER"]):
407
+ try:
408
+ self.heartbeat(queue, task_ids, log, locks, queue_lock)
409
+ except Exception:
410
+ log.exception("task heartbeat failed")
411
+
389
412
  def execute(
390
413
  self,
391
414
  queue: str,
@@ -394,5 +417,27 @@ class SyncExecutor(Executor):
394
417
  locks: Collection[Lock],
395
418
  queue_lock: Optional[Semaphore],
396
419
  ) -> bool:
420
+ # Run heartbeat thread.
421
+ all_task_ids = {task.id for task in tasks}
422
+ stop_event = threading.Event()
423
+ heartbeat_thread = threading.Thread(
424
+ target=self._periodic_heartbeat,
425
+ kwargs={
426
+ "queue": queue,
427
+ "task_ids": all_task_ids,
428
+ "log": log,
429
+ "locks": locks,
430
+ "queue_lock": queue_lock,
431
+ "stop_event": stop_event,
432
+ },
433
+ )
434
+ heartbeat_thread.start()
435
+
397
436
  # Run the tasks.
398
- return self.execute_tasks(tasks, log)
437
+ result = self.execute_tasks(tasks, log)
438
+
439
+ # Stop the heartbeat thread.
440
+ stop_event.set()
441
+ heartbeat_thread.join()
442
+
443
+ return result
@@ -674,6 +674,8 @@ class Worker:
674
674
  lock = self.connection.lock(
675
675
  self._key("lockv2", lock_id),
676
676
  timeout=self.config["ACTIVE_TASK_UPDATE_TIMEOUT"],
677
+ # Sync worker uses a thread to renew the lock.
678
+ thread_local=False,
677
679
  )
678
680
  if not lock.acquire(blocking=False):
679
681
  log.info("could not acquire lock", task_id=task.id)
@@ -1,3 +1,26 @@
1
+ Metadata-Version: 2.1
2
+ Name: tasktiger
3
+ Version: 0.19.2
4
+ Summary: Python task queue
5
+ Home-page: http://github.com/closeio/tasktiger
6
+ License: MIT
7
+ Classifier: Intended Audience :: Developers
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Operating System :: MacOS :: MacOS X
10
+ Classifier: Operating System :: POSIX
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ License-File: LICENSE
20
+ Requires-Dist: click
21
+ Requires-Dist: redis<5,>=3.3.0
22
+ Requires-Dist: structlog
23
+
1
24
  =========
2
25
  TaskTiger
3
26
  =========
@@ -18,13 +41,21 @@ TaskTiger
18
41
  Features
19
42
  --------
20
43
 
21
- - Per-task fork
44
+ - Per-task fork or synchronous worker
45
+
46
+ By default, TaskTiger forks a subprocess for each task, This comes with
47
+ several benefits: Memory leaks caused by tasks are avoided since the
48
+ subprocess is terminated when the task is finished. A hard time limit can be
49
+ set for each task, after which the task is killed if it hasn't completed. To
50
+ ensure performance, any necessary Python modules can be preloaded in the
51
+ parent process.
22
52
 
23
- TaskTiger forks a subprocess for each task, This comes with several benefits:
24
- Memory leaks caused by tasks are avoided since the subprocess is terminated
25
- when the task is finished. A hard time limit can be set for each task, after
26
- which the task is killed if it hasn't completed. To ensure performance, any
27
- necessary Python modules can be preloaded in the parent process.
53
+ TaskTiger also supports synchronous workers, which allows for better
54
+ performance due to no forking overhead, and tasks have the ability to reuse
55
+ network connections. To prevent memory leaks from accumulating, workers can
56
+ be set to shutdown after a certain amount of time, at which point a
57
+ supervisor can restart them. Workers also automatically exit on on hard
58
+ timeouts to prevent an inconsistent process state.
28
59
 
29
60
  - Unique queues
30
61
 
@@ -552,6 +583,18 @@ Workers support the following options:
552
583
 
553
584
  Store tracebacks with execution history (config defaults to ``True``).
554
585
 
586
+ - ``--executor``
587
+
588
+ Can be ``fork`` (default) or ``sync``. Whether to execute tasks in a separate
589
+ process via fork, or execute them synchronously in the same proces. See
590
+ "Features" section for the benefits of either approach.
591
+
592
+ - ``--exit-after``
593
+
594
+ Exit the worker after the time in minutes has elapsed. This is mainly useful
595
+ with the synchronous executor to prevent memory leaks from accumulating.
596
+
597
+
555
598
  In some cases it is convenient to have a custom TaskTiger launch script. For
556
599
  example, your application may have a ``manage.py`` command that sets up the
557
600
  environment and you may want to launch TaskTiger workers using that script. To
@@ -8,13 +8,17 @@ import pytest
8
8
  from freezefrog import FreezeTime
9
9
 
10
10
  from tasktiger import Task, Worker
11
+ from tasktiger._internal import ACTIVE
11
12
  from tasktiger.executor import SyncExecutor
13
+ from tasktiger.worker import LOCK_REDIS_KEY
12
14
 
15
+ from .config import DELAY
13
16
  from .tasks import (
14
17
  exception_task,
15
18
  long_task_killed,
16
19
  long_task_ok,
17
20
  simple_task,
21
+ sleep_task,
18
22
  wait_for_long_task,
19
23
  )
20
24
  from .test_base import BaseTestCase
@@ -35,10 +39,12 @@ class TestMaxWorkers(BaseTestCase):
35
39
 
36
40
  # Start two workers and wait until they start processing.
37
41
  worker1 = Process(
38
- target=external_worker, kwargs={"max_workers_per_queue": 2}
42
+ target=external_worker,
43
+ kwargs={"worker_kwargs": {"max_workers_per_queue": 2}},
39
44
  )
40
45
  worker2 = Process(
41
- target=external_worker, kwargs={"max_workers_per_queue": 2}
46
+ target=external_worker,
47
+ kwargs={"worker_kwargs": {"max_workers_per_queue": 2}},
42
48
  )
43
49
  worker1.start()
44
50
  worker2.start()
@@ -181,3 +187,54 @@ class TestSyncExecutorWorker:
181
187
  with pytest.raises(SystemExit):
182
188
  worker.run(once=True, force_once=True)
183
189
  ensure_queues(error={"default": 1})
190
+
191
+ def test_heartbeat(self, tiger):
192
+ # Test both task heartbeat and lock renewal.
193
+ # We set unique=True so the task ID matches the lock key.
194
+ task = Task(tiger, sleep_task, lock=True, unique=True)
195
+ task.delay()
196
+
197
+ # Start a worker and wait until it starts processing.
198
+ worker = Process(
199
+ target=external_worker,
200
+ kwargs={
201
+ "patch_config": {"ACTIVE_TASK_UPDATE_TIMER": DELAY / 2},
202
+ "worker_kwargs": {
203
+ # Test queue lock.
204
+ "max_workers_per_queue": 1,
205
+ "executor_class": SyncExecutor,
206
+ },
207
+ },
208
+ )
209
+ worker.start()
210
+
211
+ time.sleep(DELAY)
212
+
213
+ queue_key = tiger._key(ACTIVE, "default")
214
+ queue_lock_key = tiger._key(LOCK_REDIS_KEY, "default")
215
+ task_lock_key = tiger._key("lockv2", task.id)
216
+
217
+ conn = tiger.connection
218
+
219
+ heartbeat_1 = conn.zscore(queue_key, task.id)
220
+ queue_lock_1 = conn.zrange(queue_lock_key, 0, -1, withscores=True)[0][
221
+ 1
222
+ ]
223
+ task_lock_1 = conn.pttl(task_lock_key)
224
+
225
+ time.sleep(DELAY / 2)
226
+
227
+ heartbeat_2 = conn.zscore(queue_key, task.id)
228
+ queue_lock_2 = conn.zrange(queue_lock_key, 0, -1, withscores=True)[0][
229
+ 1
230
+ ]
231
+ task_lock_2 = conn.pttl(task_lock_key)
232
+
233
+ assert heartbeat_2 > heartbeat_1 > 0
234
+ assert queue_lock_2 > queue_lock_1 > 0
235
+
236
+ # Active task update timeout is 2 * DELAY and we renew every DELAY / 2.
237
+ assert task_lock_1 > DELAY
238
+ assert task_lock_2 > DELAY
239
+
240
+ worker.kill()
@@ -70,7 +70,7 @@ def get_tiger():
70
70
  return tiger
71
71
 
72
72
 
73
- def external_worker(n=None, patch_config=None, max_workers_per_queue=None):
73
+ def external_worker(n=None, patch_config=None, worker_kwargs=None):
74
74
  """
75
75
  Runs a worker. To be used with multiprocessing.Pool.map.
76
76
  """
@@ -79,12 +79,11 @@ def external_worker(n=None, patch_config=None, max_workers_per_queue=None):
79
79
  if patch_config:
80
80
  tiger.config.update(patch_config)
81
81
 
82
- worker = Worker(tiger)
82
+ if worker_kwargs is None:
83
+ worker_kwargs = {}
83
84
 
84
- if max_workers_per_queue is not None:
85
- worker.max_workers_per_queue = max_workers_per_queue
85
+ Worker(tiger, **worker_kwargs).run(once=True, force_once=True)
86
86
 
87
- worker.run(once=True, force_once=True)
88
87
  tiger.connection.close()
89
88
 
90
89
 
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