plain.jobs 0.33.0__py3-none-any.whl → 0.34.0__py3-none-any.whl
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.
Potentially problematic release.
This version of plain.jobs might be problematic. Click here for more details.
- plain/jobs/CHANGELOG.md +11 -0
- plain/jobs/README.md +5 -3
- plain/jobs/cli.py +64 -19
- {plain_jobs-0.33.0.dist-info → plain_jobs-0.34.0.dist-info}/METADATA +6 -4
- {plain_jobs-0.33.0.dist-info → plain_jobs-0.34.0.dist-info}/RECORD +7 -7
- {plain_jobs-0.33.0.dist-info → plain_jobs-0.34.0.dist-info}/WHEEL +0 -0
- {plain_jobs-0.33.0.dist-info → plain_jobs-0.34.0.dist-info}/licenses/LICENSE +0 -0
plain/jobs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# plain-jobs changelog
|
|
2
2
|
|
|
3
|
+
## [0.34.0](https://github.com/dropseed/plain/releases/plain-jobs@0.34.0) (2025-10-13)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- Added `--reload` flag to `plain jobs worker` command for automatic reloading when code changes are detected ([f3db87e9aa](https://github.com/dropseed/plain/commit/f3db87e9aa))
|
|
8
|
+
- Worker reloader now only watches `.py` and `.env*` files, not HTML files ([f2f31c288b](https://github.com/dropseed/plain/commit/f2f31c288b))
|
|
9
|
+
|
|
10
|
+
### Upgrade instructions
|
|
11
|
+
|
|
12
|
+
- Custom autoreloaders for development are no longer needed -- use the built-in `--reload` flag instead
|
|
13
|
+
|
|
3
14
|
## [0.33.0](https://github.com/dropseed/plain/releases/plain-jobs@0.33.0) (2025-10-10)
|
|
4
15
|
|
|
5
16
|
### What's changed
|
plain/jobs/README.md
CHANGED
|
@@ -55,15 +55,17 @@ plain migrate
|
|
|
55
55
|
|
|
56
56
|
## Local development
|
|
57
57
|
|
|
58
|
-
In development, you will typically want to run the worker alongside your app. With [`plain.dev`](/plain-dev/plain/dev/README.md) you can do this by adding it to the `[tool.plain.dev.run]` section of your `pyproject.toml` file.
|
|
58
|
+
In development, you will typically want to run the worker alongside your app with auto-reloading enabled. With [`plain.dev`](/plain-dev/plain/dev/README.md) you can do this by adding it to the `[tool.plain.dev.run]` section of your `pyproject.toml` file.
|
|
59
59
|
|
|
60
60
|
```toml
|
|
61
61
|
# pyproject.toml
|
|
62
62
|
[tool.plain.dev.run]
|
|
63
|
-
worker = {cmd = "
|
|
64
|
-
worker-slow = {cmd = "
|
|
63
|
+
worker = {cmd = "plain jobs worker --reload --stats-every 0 --max-processes 2"}
|
|
64
|
+
worker-slow = {cmd = "plain jobs worker --reload --queue slow --stats-every 0 --max-processes 2"}
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
The `--reload` flag will automatically watch `.py` and `.env*` files for changes and restart the worker when changes are detected.
|
|
68
|
+
|
|
67
69
|
## Job parameters
|
|
68
70
|
|
|
69
71
|
When calling `run_in_worker()`, you can specify several parameters to control job execution:
|
plain/jobs/cli.py
CHANGED
|
@@ -62,35 +62,80 @@ def cli() -> None:
|
|
|
62
62
|
type=int,
|
|
63
63
|
envvar="PLAIN_JOBS_WORKER_STATS_EVERY",
|
|
64
64
|
)
|
|
65
|
+
@click.option(
|
|
66
|
+
"--reload",
|
|
67
|
+
is_flag=True,
|
|
68
|
+
help="Watch files and auto-reload worker on changes",
|
|
69
|
+
)
|
|
65
70
|
def worker(
|
|
66
71
|
queues: tuple[str, ...],
|
|
67
72
|
max_processes: int | None,
|
|
68
73
|
max_jobs_per_process: int | None,
|
|
69
74
|
max_pending_per_process: int,
|
|
70
75
|
stats_every: int,
|
|
76
|
+
reload: bool,
|
|
71
77
|
) -> None:
|
|
72
78
|
"""Run the job worker."""
|
|
73
79
|
jobs_schedule = load_schedule(settings.JOBS_SCHEDULE)
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
if reload:
|
|
82
|
+
from plain.internal.reloader import Reloader
|
|
83
|
+
|
|
84
|
+
# Track whether we should continue restarting
|
|
85
|
+
should_restart = {"value": True}
|
|
86
|
+
current_worker = {"instance": None}
|
|
87
|
+
|
|
88
|
+
def file_changed(filename: str) -> None:
|
|
89
|
+
if current_worker["instance"]:
|
|
90
|
+
current_worker["instance"].shutdown()
|
|
91
|
+
|
|
92
|
+
def signal_shutdown(signalnum: int, _: Any) -> None:
|
|
93
|
+
should_restart["value"] = False
|
|
94
|
+
if current_worker["instance"]:
|
|
95
|
+
current_worker["instance"].shutdown()
|
|
96
|
+
|
|
97
|
+
# Allow the worker to be stopped gracefully on SIGTERM/SIGINT
|
|
98
|
+
signal.signal(signal.SIGTERM, signal_shutdown)
|
|
99
|
+
signal.signal(signal.SIGINT, signal_shutdown)
|
|
100
|
+
|
|
101
|
+
# Start file watcher once, outside the loop
|
|
102
|
+
reloader = Reloader(callback=file_changed, watch_html=False)
|
|
103
|
+
reloader.start()
|
|
104
|
+
|
|
105
|
+
while should_restart["value"]:
|
|
106
|
+
worker = Worker(
|
|
107
|
+
queues=list(queues),
|
|
108
|
+
jobs_schedule=jobs_schedule,
|
|
109
|
+
max_processes=max_processes,
|
|
110
|
+
max_jobs_per_process=max_jobs_per_process,
|
|
111
|
+
max_pending_per_process=max_pending_per_process,
|
|
112
|
+
stats_every=stats_every,
|
|
113
|
+
)
|
|
114
|
+
current_worker["instance"] = worker
|
|
115
|
+
|
|
116
|
+
# Start processing jobs (blocks until shutdown)
|
|
117
|
+
worker.run()
|
|
118
|
+
|
|
119
|
+
else:
|
|
120
|
+
worker = Worker(
|
|
121
|
+
queues=list(queues),
|
|
122
|
+
jobs_schedule=jobs_schedule,
|
|
123
|
+
max_processes=max_processes,
|
|
124
|
+
max_jobs_per_process=max_jobs_per_process,
|
|
125
|
+
max_pending_per_process=max_pending_per_process,
|
|
126
|
+
stats_every=stats_every,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def _shutdown(signalnum: int, _: Any) -> None:
|
|
130
|
+
logger.info("Job worker shutdown signal received signalnum=%s", signalnum)
|
|
131
|
+
worker.shutdown()
|
|
132
|
+
|
|
133
|
+
# Allow the worker to be stopped gracefully on SIGTERM
|
|
134
|
+
signal.signal(signal.SIGTERM, _shutdown)
|
|
135
|
+
signal.signal(signal.SIGINT, _shutdown)
|
|
136
|
+
|
|
137
|
+
# Start processing jobs
|
|
138
|
+
worker.run()
|
|
94
139
|
|
|
95
140
|
|
|
96
141
|
@cli.command()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plain.jobs
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.34.0
|
|
4
4
|
Summary: Process background jobs with a database-driven job queue.
|
|
5
5
|
Author-email: Dave Gaeddert <dave.gaeddert@dropseed.dev>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -66,15 +66,17 @@ plain migrate
|
|
|
66
66
|
|
|
67
67
|
## Local development
|
|
68
68
|
|
|
69
|
-
In development, you will typically want to run the worker alongside your app. With [`plain.dev`](/plain-dev/plain/dev/README.md) you can do this by adding it to the `[tool.plain.dev.run]` section of your `pyproject.toml` file.
|
|
69
|
+
In development, you will typically want to run the worker alongside your app with auto-reloading enabled. With [`plain.dev`](/plain-dev/plain/dev/README.md) you can do this by adding it to the `[tool.plain.dev.run]` section of your `pyproject.toml` file.
|
|
70
70
|
|
|
71
71
|
```toml
|
|
72
72
|
# pyproject.toml
|
|
73
73
|
[tool.plain.dev.run]
|
|
74
|
-
worker = {cmd = "
|
|
75
|
-
worker-slow = {cmd = "
|
|
74
|
+
worker = {cmd = "plain jobs worker --reload --stats-every 0 --max-processes 2"}
|
|
75
|
+
worker-slow = {cmd = "plain jobs worker --reload --queue slow --stats-every 0 --max-processes 2"}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
The `--reload` flag will automatically watch `.py` and `.env*` files for changes and restart the worker when changes are detected.
|
|
79
|
+
|
|
78
80
|
## Job parameters
|
|
79
81
|
|
|
80
82
|
When calling `run_in_worker()`, you can specify several parameters to control job execution:
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
plain/jobs/CHANGELOG.md,sha256=
|
|
2
|
-
plain/jobs/README.md,sha256=
|
|
1
|
+
plain/jobs/CHANGELOG.md,sha256=6jaE6mdMVx7jX9UFk5eEqT31LC0CgRVTJHGrwObeES4,9384
|
|
2
|
+
plain/jobs/README.md,sha256=Xuhz2Q48G9WeGCh5OWGVBlaSea4eKCqWzcTAtZRrS0I,6835
|
|
3
3
|
plain/jobs/__init__.py,sha256=p2ATql3HyPzPTV34gJQ04caT7tcNQLbBGM6uIoDPbjo,92
|
|
4
4
|
plain/jobs/admin.py,sha256=IhB6nkHKHB5CJfwPEoNW4pQKUi_4ewpNGkOCo4XwO0g,6719
|
|
5
5
|
plain/jobs/chores.py,sha256=5WdLlCDPppX78yfS4LczIG7UeVR9DAoJsJHTT2Codd4,483
|
|
6
|
-
plain/jobs/cli.py,sha256=
|
|
6
|
+
plain/jobs/cli.py,sha256=KnazGup1JumjrSjhoMO2FwgLBATRW70YewkdMcLzsrI,5683
|
|
7
7
|
plain/jobs/config.py,sha256=PQsl-LxWsWLnjC98f0mvtdcCOuXvXKDMjrCRf1fq44Y,550
|
|
8
8
|
plain/jobs/default_settings.py,sha256=r_95ucg_KY1XW1jarZy8VO3p-ylbllKMUrHzOPJiX6U,227
|
|
9
9
|
plain/jobs/jobs.py,sha256=IPQ2vlhfLm5gvdZTR52WINDAWRUPN0Mjc_EhKjqYhAk,7843
|
|
@@ -21,7 +21,7 @@ plain/jobs/migrations/0005_rename_constraints_and_indexes.py,sha256=PDGpOw6__tVf
|
|
|
21
21
|
plain/jobs/migrations/0006_alter_jobprocess_table_alter_jobrequest_table_and_more.py,sha256=FY0_pcw0mL8MkUSatpDXWtA_xQw0kTZBGIyjLcmYeJE,546
|
|
22
22
|
plain/jobs/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
plain/jobs/templates/admin/plainqueue/jobresult_detail.html,sha256=Ybp1s_dARo_bFDcLEzEfETheP8SzqHHE_NNSKhv_eh8,198
|
|
24
|
-
plain_jobs-0.
|
|
25
|
-
plain_jobs-0.
|
|
26
|
-
plain_jobs-0.
|
|
27
|
-
plain_jobs-0.
|
|
24
|
+
plain_jobs-0.34.0.dist-info/METADATA,sha256=8uXilZ1ZfAqKsipubMNFgbcBY6KD2JLa7eGqavgtZTk,7162
|
|
25
|
+
plain_jobs-0.34.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
plain_jobs-0.34.0.dist-info/licenses/LICENSE,sha256=cvKM3OlqHx3ijD6e34zsSUkPvzl-ya3Dd63A6EHL94U,1500
|
|
27
|
+
plain_jobs-0.34.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|