Skip to content

Commit

Permalink
Remove dedicated task signals
Browse files Browse the repository at this point in the history
The global ones can be used, and restored later if needed. The implementation is a bit of a bodge
  • Loading branch information
RealOrangeOne committed Sep 13, 2024
1 parent 5552edf commit bf7abd1
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 43 deletions.
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,6 @@ Whilst signals are available, they may not be the most maintainable approach.
- `django_tasks.signals.task_enqueued`: Called when a task is enqueued. The sender is the backend class. Also called with the enqueued `task_result`.
- `django_tasks.signals.task_finished`: Called when a task finishes (`COMPLETE` or `FAILED`). The sender is the backend class. Also called with the finished `task_result`.

Additionally, each `Task` has its own signals. These signals are only sent for the given `Task`, whilst the above will be called for all `Task`s.

- `Task.finished`: Called when the task finishes (`COMPLETE` or `FAILED`). There is no sender (`None`), however the handler is called with the finished `task_result`.

Tasks which are modified by `.using` have the same signal.

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md) for information on how to contribute.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ def run_task(self, db_task_result: DBTaskResult) -> None:
# Setting the return and success value inside the error handling,
# So errors setting it (eg JSON encode) can still be recorded
db_task_result.set_complete(return_value)
task_result.task.finished.send(sender=None, task_result=task_result)
task_finished.send(
sender=type(task.get_backend()), task_result=db_task_result.task_result
)
Expand All @@ -146,7 +145,6 @@ def run_task(self, db_task_result: DBTaskResult) -> None:
except (ModuleNotFoundError, SuspiciousOperation):
logger.exception("Task id=%s failed unexpectedly", db_task_result.id)
else:
task_result.task.finished.send(sender=None, task_result=task_result)
task_finished.send(
sender=sender,
task_result=task_result,
Expand Down
2 changes: 0 additions & 2 deletions django_tasks/backends/immediate.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,11 @@ def _execute_task(self, task_result: TaskResult) -> None:

object.__setattr__(task_result, "status", ResultStatus.FAILED)

task_result.task.finished.send(sender=None, task_result=task_result)
task_finished.send(type(self), task_result=task_result)
else:
object.__setattr__(task_result, "finished_at", timezone.now())
object.__setattr__(task_result, "status", ResultStatus.COMPLETE)

task_result.task.finished.send(sender=None, task_result=task_result)
task_finished.send(type(self), task_result=task_result)

def enqueue(
Expand Down
18 changes: 0 additions & 18 deletions django_tasks/task.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from dataclasses import dataclass, field, replace
from datetime import datetime, timedelta
from functools import lru_cache
from inspect import iscoroutinefunction
from typing import (
TYPE_CHECKING,
Expand All @@ -17,7 +16,6 @@

from asgiref.sync import async_to_sync, sync_to_async
from django.db.models.enums import TextChoices
from django.dispatch import Signal
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.module_loading import import_string
Expand Down Expand Up @@ -56,17 +54,6 @@ class ResultStatus(TextChoices):
COMPLETE = ("COMPLETE", _("Complete"))


# Use a large number to ensure `lru_cache` still uses a lock
@lru_cache(maxsize=100000)
def _get_task_signal(task: "Task", name: str) -> Signal:
"""
Allow a Task to have a signal, without storing it on the task itself.
This allows the Task to still be hashable, picklable and deepcopyable.
"""
return Signal()


T = TypeVar("T")
P = ParamSpec("P")

Expand Down Expand Up @@ -198,11 +185,6 @@ def is_modified(self) -> bool:
"""
return self != self.original

@property
def finished(self) -> Signal:
"""A signal, fired when the task finished"""
return _get_task_signal(self.original, "finished")


# Bare decorator usage
# e.g. @task
Expand Down
15 changes: 0 additions & 15 deletions tests/tests/test_tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import dataclasses
from copy import deepcopy
from datetime import datetime, timedelta

from django.dispatch import Signal
from django.test import SimpleTestCase, override_settings
from django.utils import timezone
from django.utils.module_loading import import_string
Expand Down Expand Up @@ -259,16 +257,3 @@ def test_original(self) -> None:
def test_is_modified(self) -> None:
self.assertFalse(test_tasks.noop_task.is_modified)
self.assertTrue(test_tasks.noop_task.using(priority=10).is_modified)

def test_finished_signal(self) -> None:
self.assertIsInstance(test_tasks.noop_task.finished, Signal)
self.assertIs(
test_tasks.noop_task.using().finished, test_tasks.noop_task.finished
)
self.assertIs(
test_tasks.noop_task.using(priority=10).finished,
test_tasks.noop_task.finished,
)
self.assertIs(
deepcopy(test_tasks.noop_task).finished, test_tasks.noop_task.finished
)

0 comments on commit bf7abd1

Please sign in to comment.