django-crontask 1.2.0__tar.gz → 2.0.0__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.
- {django_crontask-1.2.0 → django_crontask-2.0.0}/PKG-INFO +10 -1
- {django_crontask-1.2.0 → django_crontask-2.0.0}/README.md +9 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/__init__.py +19 -29
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/_version.py +3 -3
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/contrib/sentry.py +11 -5
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/utils.py +3 -1
- {django_crontask-1.2.0 → django_crontask-2.0.0}/LICENSE +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/conf.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/contrib/__init__.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/management/__init__.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/management/commands/__init__.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/management/commands/crontask.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/crontask/tasks.py +0 -0
- {django_crontask-1.2.0 → django_crontask-2.0.0}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-crontask
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Cron style scheduler for Django's task framework.
|
|
5
5
|
Keywords: Django,cron,tasks,scheduler
|
|
6
6
|
Author-email: Rust Saiargaliev <fly.amureki@gmail.com>, Johannes Maron <johannes@maron.family>, Mostafa Mohamed <mostafa.anm91@gmail.com>, Jacqueline Kraus <jacquelinekraus1992@gmail.com>
|
|
@@ -152,6 +152,15 @@ The monitor's slug will be the actor's name. Like `my_task` in the example above
|
|
|
152
152
|
Certain triggers are not supported by Sentry as well as sub-minute intervals.
|
|
153
153
|
In these cases, no monitor will be created and no telemetry will be sent.
|
|
154
154
|
|
|
155
|
+
Pass a custom config via `sentry_monitor_config` or set it to `None`
|
|
156
|
+
to disable Sentry monitoring for a single task:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
@cron("* * * * *", sentry_monitor_config=None)
|
|
160
|
+
@task
|
|
161
|
+
def my_task_without_sentry(): ...
|
|
162
|
+
```
|
|
163
|
+
|
|
155
164
|
### The crontask command
|
|
156
165
|
|
|
157
166
|
```ShellSession
|
|
@@ -110,6 +110,15 @@ The monitor's slug will be the actor's name. Like `my_task` in the example above
|
|
|
110
110
|
Certain triggers are not supported by Sentry as well as sub-minute intervals.
|
|
111
111
|
In these cases, no monitor will be created and no telemetry will be sent.
|
|
112
112
|
|
|
113
|
+
Pass a custom config via `sentry_monitor_config` or set it to `None`
|
|
114
|
+
to disable Sentry monitoring for a single task:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
@cron("* * * * *", sentry_monitor_config=None)
|
|
118
|
+
@task
|
|
119
|
+
def my_task_without_sentry(): ...
|
|
120
|
+
```
|
|
121
|
+
|
|
113
122
|
### The crontask command
|
|
114
123
|
|
|
115
124
|
```ShellSession
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
"""Cron style scheduler for Django's task framework."""
|
|
2
2
|
|
|
3
3
|
import typing
|
|
4
|
-
import warnings
|
|
5
4
|
from unittest.mock import Mock
|
|
6
5
|
|
|
7
6
|
from apscheduler.schedulers.base import STATE_STOPPED
|
|
8
7
|
from apscheduler.schedulers.blocking import BlockingScheduler
|
|
9
8
|
from apscheduler.triggers.base import BaseTrigger
|
|
10
9
|
from apscheduler.triggers.cron import CronTrigger
|
|
11
|
-
from apscheduler.triggers.interval import IntervalTrigger
|
|
12
10
|
from django.tasks import Task
|
|
13
11
|
from django.utils import timezone
|
|
14
12
|
|
|
15
13
|
from . import _version
|
|
16
14
|
from .contrib import sentry
|
|
17
15
|
|
|
18
|
-
__all__ = ["cron", "
|
|
16
|
+
__all__ = ["cron", "scheduler", "VERSION", "__version__"]
|
|
19
17
|
|
|
20
18
|
__version__ = _version.version
|
|
21
19
|
VERSION = _version.version_tuple
|
|
@@ -34,9 +32,14 @@ class LazyBlockingScheduler(BlockingScheduler):
|
|
|
34
32
|
|
|
35
33
|
|
|
36
34
|
scheduler = LazyBlockingScheduler()
|
|
35
|
+
UNSET = object()
|
|
37
36
|
|
|
38
37
|
|
|
39
|
-
def cron(
|
|
38
|
+
def cron(
|
|
39
|
+
schedule: str | BaseTrigger,
|
|
40
|
+
*,
|
|
41
|
+
sentry_monitor_config: dict[str, dict[str, str | int] | str] | None = UNSET,
|
|
42
|
+
) -> typing.Callable[[Task], Task]:
|
|
40
43
|
"""
|
|
41
44
|
Run task on a scheduler with a cron schedule.
|
|
42
45
|
|
|
@@ -46,8 +49,10 @@ def cron(schedule: str | BaseTrigger) -> typing.Callable[[Task], Task]:
|
|
|
46
49
|
def cron_test():
|
|
47
50
|
print("Cron test")
|
|
48
51
|
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
Args:
|
|
53
|
+
schedule: A cron schedule string or an APScheduler trigger.
|
|
54
|
+
sentry_monitor_config: A Sentry monitor configuration dict or None to disable monitoring.
|
|
55
|
+
|
|
51
56
|
"""
|
|
52
57
|
|
|
53
58
|
def decorator(task: Task) -> Task:
|
|
@@ -67,7 +72,14 @@ def cron(schedule: str | BaseTrigger) -> typing.Callable[[Task], Task]:
|
|
|
67
72
|
else:
|
|
68
73
|
trigger = schedule
|
|
69
74
|
|
|
70
|
-
|
|
75
|
+
if sentry_monitor_config is not None:
|
|
76
|
+
task = sentry.monitor_cron_task(
|
|
77
|
+
task,
|
|
78
|
+
trigger,
|
|
79
|
+
sentry_monitor_config={}
|
|
80
|
+
if sentry_monitor_config is UNSET
|
|
81
|
+
else sentry_monitor_config,
|
|
82
|
+
)
|
|
71
83
|
|
|
72
84
|
scheduler.add_job(
|
|
73
85
|
func=task.enqueue,
|
|
@@ -79,25 +91,3 @@ def cron(schedule: str | BaseTrigger) -> typing.Callable[[Task], Task]:
|
|
|
79
91
|
return task
|
|
80
92
|
|
|
81
93
|
return decorator
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
def interval(*, seconds):
|
|
85
|
-
"""
|
|
86
|
-
Run task on a periodic interval.
|
|
87
|
-
|
|
88
|
-
The interval decorator is deprecated and will be removed in a future release.
|
|
89
|
-
Please use the cron decorator with an 'IntervalTrigger' instead.
|
|
90
|
-
"""
|
|
91
|
-
warnings.warn(
|
|
92
|
-
"The interval decorator is deprecated and will be removed in a future release. "
|
|
93
|
-
"Please use the cron decorator with an 'IntervalTrigger' instead.",
|
|
94
|
-
DeprecationWarning,
|
|
95
|
-
stacklevel=2,
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
return cron(
|
|
99
|
-
IntervalTrigger(
|
|
100
|
-
seconds=seconds,
|
|
101
|
-
timezone=timezone.get_default_timezone(),
|
|
102
|
-
)
|
|
103
|
-
)
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '
|
|
22
|
-
__version_tuple__ = version_tuple = (
|
|
21
|
+
__version__ = version = '2.0.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (2, 0, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gfbe0c7d7f'
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
1
|
from apscheduler.triggers.base import BaseTrigger
|
|
4
2
|
from apscheduler.triggers.calendarinterval import CalendarIntervalTrigger
|
|
5
3
|
from apscheduler.triggers.cron import CronTrigger
|
|
@@ -8,7 +6,9 @@ from django.tasks import Task
|
|
|
8
6
|
from django.utils import timezone
|
|
9
7
|
|
|
10
8
|
|
|
11
|
-
def trigger_to_monitor_config(
|
|
9
|
+
def trigger_to_monitor_config(
|
|
10
|
+
trigger: BaseTrigger,
|
|
11
|
+
) -> dict[str, dict[str, str | int] | str] | None:
|
|
12
12
|
"""Convert an APScheduler trigger to a Sentry monitor configuration if possible."""
|
|
13
13
|
tz = str(timezone.get_default_timezone())
|
|
14
14
|
match trigger:
|
|
@@ -62,7 +62,11 @@ def trigger_to_monitor_config(trigger: BaseTrigger) -> dict[str, typing.Any] | N
|
|
|
62
62
|
return None
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def monitor_cron_task(
|
|
65
|
+
def monitor_cron_task(
|
|
66
|
+
task: Task,
|
|
67
|
+
trigger: BaseTrigger,
|
|
68
|
+
sentry_monitor_config: dict[str, dict[str, str | int] | str],
|
|
69
|
+
) -> Task:
|
|
66
70
|
"""
|
|
67
71
|
Wrap the task function in a Sentry monitor for a suitable trigger.
|
|
68
72
|
|
|
@@ -75,7 +79,9 @@ def monitor_cron_task(task: Task, trigger: BaseTrigger) -> Task:
|
|
|
75
79
|
except ImportError:
|
|
76
80
|
return task
|
|
77
81
|
else:
|
|
78
|
-
if monitor_config := trigger_to_monitor_config(
|
|
82
|
+
if monitor_config := sentry_monitor_config or trigger_to_monitor_config(
|
|
83
|
+
trigger
|
|
84
|
+
):
|
|
79
85
|
return type(task)(
|
|
80
86
|
priority=task.priority,
|
|
81
87
|
func=monitor(task.name, monitor_config=monitor_config)(task.func),
|
|
@@ -41,5 +41,7 @@ def extend_lock(lock, scheduler):
|
|
|
41
41
|
try:
|
|
42
42
|
lock.extend(get_settings().LOCK_TIMEOUT, True)
|
|
43
43
|
except LockError:
|
|
44
|
-
scheduler
|
|
44
|
+
# `extend_lock` runs inside a scheduler worker thread;
|
|
45
|
+
# shutdown must be done from there to avoid a deadlock on the lock.
|
|
46
|
+
scheduler.shutdown(wait=False)
|
|
45
47
|
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
|