|
8 | 8 | from types import FrameType |
9 | 9 | from typing import List, Optional |
10 | 10 |
|
| 11 | +from django.core.exceptions import SuspiciousOperation |
11 | 12 | from django.core.management.base import BaseCommand |
12 | 13 | from django.db import connections |
13 | 14 | from django.db.utils import OperationalError |
|
17 | 18 | from django_tasks.backends.database.models import DBTaskResult |
18 | 19 | from django_tasks.backends.database.utils import exclusive_transaction |
19 | 20 | from django_tasks.exceptions import InvalidTaskBackendError |
20 | | -from django_tasks.task import DEFAULT_QUEUE_NAME, ResultStatus |
| 21 | +from django_tasks.signals import task_finished |
| 22 | +from django_tasks.task import DEFAULT_QUEUE_NAME |
21 | 23 |
|
| 24 | +package_logger = logging.getLogger("django_tasks") |
22 | 25 | logger = logging.getLogger("django_tasks.backends.database.db_worker") |
23 | 26 |
|
24 | 27 |
|
@@ -124,28 +127,28 @@ def run_task(self, db_task_result: DBTaskResult) -> None: |
124 | 127 | "Task id=%s path=%s state=%s", |
125 | 128 | db_task_result.id, |
126 | 129 | db_task_result.task_path, |
127 | | - ResultStatus.RUNNING, |
| 130 | + task_result.status, |
128 | 131 | ) |
129 | 132 | return_value = task.call(*task_result.args, **task_result.kwargs) |
130 | 133 |
|
131 | 134 | # Setting the return and success value inside the error handling, |
132 | 135 | # So errors setting it (eg JSON encode) can still be recorded |
133 | 136 | db_task_result.set_complete(return_value) |
134 | | - logger.info( |
135 | | - "Task id=%s path=%s state=%s", |
136 | | - db_task_result.id, |
137 | | - db_task_result.task_path, |
138 | | - ResultStatus.COMPLETE, |
| 137 | + task_finished.send( |
| 138 | + sender=type(task.get_backend()), task_result=db_task_result.task_result |
139 | 139 | ) |
140 | 140 | except BaseException as e: |
141 | | - # Use `.exception` to integrate with error monitoring tools (eg Sentry) |
142 | | - logger.exception( |
143 | | - "Task id=%s path=%s state=%s", |
144 | | - db_task_result.id, |
145 | | - db_task_result.task_path, |
146 | | - ResultStatus.FAILED, |
147 | | - ) |
148 | 141 | db_task_result.set_failed(e) |
| 142 | + try: |
| 143 | + sender = type(db_task_result.task.get_backend()) |
| 144 | + task_result = db_task_result.task_result |
| 145 | + except (ModuleNotFoundError, SuspiciousOperation): |
| 146 | + logger.exception("Task id=%s failed unexpectedly", db_task_result.id) |
| 147 | + else: |
| 148 | + task_finished.send( |
| 149 | + sender=sender, |
| 150 | + task_result=task_result, |
| 151 | + ) |
149 | 152 |
|
150 | 153 | # If the user tried to terminate, let them |
151 | 154 | if isinstance(e, KeyboardInterrupt): |
@@ -205,18 +208,18 @@ def add_arguments(self, parser: ArgumentParser) -> None: |
205 | 208 |
|
206 | 209 | def configure_logging(self, verbosity: int) -> None: |
207 | 210 | if verbosity == 0: |
208 | | - logger.setLevel(logging.CRITICAL) |
| 211 | + package_logger.setLevel(logging.CRITICAL) |
209 | 212 | elif verbosity == 1: |
210 | | - logger.setLevel(logging.WARNING) |
| 213 | + package_logger.setLevel(logging.WARNING) |
211 | 214 | elif verbosity == 2: |
212 | | - logger.setLevel(logging.INFO) |
| 215 | + package_logger.setLevel(logging.INFO) |
213 | 216 | else: |
214 | | - logger.setLevel(logging.DEBUG) |
| 217 | + package_logger.setLevel(logging.DEBUG) |
215 | 218 |
|
216 | 219 | # If no handler is configured, the logs won't show, |
217 | 220 | # regardless of the set level. |
218 | | - if not logger.hasHandlers(): |
219 | | - logger.addHandler(logging.StreamHandler(self.stdout)) |
| 221 | + if not package_logger.hasHandlers(): |
| 222 | + package_logger.addHandler(logging.StreamHandler(self.stdout)) |
220 | 223 |
|
221 | 224 | def handle( |
222 | 225 | self, |
|
0 commit comments