django-lambda-tasks 0.4.0__tar.gz → 0.4.1__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 (100) hide show
  1. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/PKG-INFO +1 -1
  2. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/local_executor.py +15 -2
  3. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/pyproject.toml +1 -1
  4. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_local_executor.py +19 -2
  5. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.github/workflows/ci.yml +0 -0
  6. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.github/workflows/release.yml +0 -0
  7. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.gitignore +0 -0
  8. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/async-local-execution/.config.kiro +0 -0
  9. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/async-local-execution/design.md +0 -0
  10. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/async-local-execution/requirements.md +0 -0
  11. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/async-local-execution/tasks.md +0 -0
  12. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/deferred-task-enqueue/.config.kiro +0 -0
  13. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/deferred-task-enqueue/design.md +0 -0
  14. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/deferred-task-enqueue/requirements.md +0 -0
  15. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/deferred-task-enqueue/tasks.md +0 -0
  16. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/eager-mode-example-app/.config.kiro +0 -0
  17. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/eager-mode-example-app/design.md +0 -0
  18. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/eager-mode-example-app/requirements.md +0 -0
  19. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/eager-mode-example-app/tasks.md +0 -0
  20. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ignore-errors-decorator-option/.config.kiro +0 -0
  21. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ignore-errors-decorator-option/design.md +0 -0
  22. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ignore-errors-decorator-option/requirements.md +0 -0
  23. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ignore-errors-decorator-option/tasks.md +0 -0
  24. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/import-string-task-resolution/.config.kiro +0 -0
  25. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/import-string-task-resolution/design.md +0 -0
  26. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/import-string-task-resolution/requirements.md +0 -0
  27. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/import-string-task-resolution/tasks.md +0 -0
  28. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/retry-delay/.config.kiro +0 -0
  29. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/retry-delay/design.md +0 -0
  30. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/retry-delay/requirements.md +0 -0
  31. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/retry-delay/tasks.md +0 -0
  32. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks/.config.kiro +0 -0
  33. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks/design.md +0 -0
  34. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks/requirements.md +0 -0
  35. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks/tasks.md +0 -0
  36. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks-bugfix/.config.kiro +0 -0
  37. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks-bugfix/bugfix.md +0 -0
  38. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks-bugfix/design.md +0 -0
  39. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/rse-background-tasks-bugfix/tasks.md +0 -0
  40. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/singleton-task/.config.kiro +0 -0
  41. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/singleton-task/design.md +0 -0
  42. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/singleton-task/requirements.md +0 -0
  43. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/singleton-task/tasks.md +0 -0
  44. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ssm-environment-loader/.config.kiro +0 -0
  45. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ssm-environment-loader/design.md +0 -0
  46. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ssm-environment-loader/requirements.md +0 -0
  47. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/ssm-environment-loader/tasks.md +0 -0
  48. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/task-retry/.config.kiro +0 -0
  49. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/task-retry/design.md +0 -0
  50. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/task-retry/requirements.md +0 -0
  51. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/specs/task-retry/tasks.md +0 -0
  52. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/steering/product.md +0 -0
  53. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/steering/structure.md +0 -0
  54. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.kiro/steering/tech.md +0 -0
  55. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.pre-commit-config.yaml +0 -0
  56. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/.vscode/settings.json +0 -0
  57. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/README.md +0 -0
  58. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/README.md +0 -0
  59. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_app/__init__.py +0 -0
  60. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_app/apps.py +0 -0
  61. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_app/tasks.py +0 -0
  62. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_app/urls.py +0 -0
  63. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_app/views.py +0 -0
  64. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_project/__init__.py +0 -0
  65. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_project/settings.py +0 -0
  66. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_project/urls.py +0 -0
  67. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/example_project/wsgi.py +0 -0
  68. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/example/manage.py +0 -0
  69. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/__init__.py +0 -0
  70. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/admin.py +0 -0
  71. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/apps.py +0 -0
  72. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/decorators.py +0 -0
  73. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/environment_loader.py +0 -0
  74. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/handler.py +0 -0
  75. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/logging.py +0 -0
  76. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/migrations/0001_initial.py +0 -0
  77. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/migrations/0002_alter_taskrecord_status.py +0 -0
  78. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/migrations/__init__.py +0 -0
  79. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/models.py +0 -0
  80. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/secret_loader.py +0 -0
  81. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/settings.py +0 -0
  82. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/tasks.py +0 -0
  83. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/lambda_tasks/timeouts.py +0 -0
  84. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/conftest.py +0 -0
  85. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/settings.py +0 -0
  86. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_admin.py +0 -0
  87. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_decorator.py +0 -0
  88. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_decorators.py +0 -0
  89. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_deferred_enqueue.py +0 -0
  90. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_environment_loader.py +0 -0
  91. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_handler.py +0 -0
  92. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_kwargs_only.py +0 -0
  93. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_logging.py +0 -0
  94. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_models.py +0 -0
  95. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_secret_loader.py +0 -0
  96. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_serializer.py +0 -0
  97. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_settings.py +0 -0
  98. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_tasks.py +0 -0
  99. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_timeout_validation.py +0 -0
  100. {django_lambda_tasks-0.4.0 → django_lambda_tasks-0.4.1}/tests/test_timeouts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-lambda-tasks
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: Run async tasks in a lambda function
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: awslambdaric
@@ -1,10 +1,13 @@
1
1
  """Process pool executor for async local task execution."""
2
2
 
3
+ import logging
3
4
  import uuid
4
- from concurrent.futures import ProcessPoolExecutor
5
+ from concurrent.futures import Future, ProcessPoolExecutor
5
6
 
6
7
  from lambda_tasks.settings import LambdaTasksSettings
7
8
 
9
+ logger = logging.getLogger(__name__)
10
+
8
11
  _pool: ProcessPoolExecutor | None = None
9
12
 
10
13
 
@@ -38,8 +41,18 @@ def _execute_in_worker(*, message_json: str, message_id: str) -> None:
38
41
  message.execute_immediately(message_id=message_id)
39
42
 
40
43
 
44
+ def _log_worker_exception(future: Future) -> None: # type: ignore[type-arg]
45
+ """Callback attached to each worker future. Logs unhandled exceptions."""
46
+ exception = future.exception()
47
+ if exception is not None:
48
+ logger.error("Worker process raised an exception", exc_info=exception)
49
+
50
+
41
51
  def submit_task(*, message_json: str) -> None:
42
52
  """Submit a task to the process pool. Fire-and-forget."""
43
53
  pool = get_pool()
44
54
  message_id = str(uuid.uuid4())
45
- pool.submit(_execute_in_worker, message_json=message_json, message_id=message_id)
55
+ future = pool.submit(
56
+ _execute_in_worker, message_json=message_json, message_id=message_id
57
+ )
58
+ future.add_done_callback(_log_worker_exception)
@@ -7,7 +7,7 @@ packages = ["lambda_tasks"]
7
7
 
8
8
  [project]
9
9
  name = "django-lambda-tasks"
10
- version = "0.4.0"
10
+ version = "0.4.1"
11
11
  description = "Run async tasks in a lambda function"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"
@@ -344,7 +344,7 @@ class TestSubmitTask:
344
344
  assert str(parsed) == message_id
345
345
 
346
346
  def test_submit_task_does_not_wait_on_future(self, settings):
347
- """submit_task() does not call .result() or .add_done_callback() on the Future.
347
+ """submit_task() does not call .result() on the Future.
348
348
 
349
349
  Validates: Requirements 3.4, 5.3
350
350
  """
@@ -363,7 +363,24 @@ class TestSubmitTask:
363
363
  )
364
364
 
365
365
  mock_future.result.assert_not_called()
366
- mock_future.add_done_callback.assert_not_called()
366
+
367
+ def test_submit_task_attaches_exception_logging_callback(self, settings):
368
+ """submit_task() attaches _log_worker_exception as a done callback."""
369
+ from lambda_tasks.local_executor import _log_worker_exception, submit_task
370
+
371
+ settings.LAMBDA_TASKS_LOCAL_WORKERS = 2
372
+ settings.LAMBDA_TASKS_EAGER = False
373
+
374
+ mock_pool = MagicMock()
375
+ mock_future = MagicMock()
376
+ mock_pool.submit.return_value = mock_future
377
+
378
+ with patch("lambda_tasks.local_executor.get_pool", return_value=mock_pool):
379
+ submit_task(
380
+ message_json='{"task_name": "myapp.tasks.foo", "kwargs": {}, "n_retries": 0}'
381
+ )
382
+
383
+ mock_future.add_done_callback.assert_called_once_with(_log_worker_exception)
367
384
 
368
385
 
369
386
  # ---------------------------------------------------------------------------