plain.jobs 0.35.0__py3-none-any.whl → 0.36.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 +24 -0
- plain/jobs/jobs.py +2 -3
- plain/jobs/models.py +11 -10
- plain/jobs/workers.py +1 -16
- {plain_jobs-0.35.0.dist-info → plain_jobs-0.36.0.dist-info}/METADATA +1 -1
- {plain_jobs-0.35.0.dist-info → plain_jobs-0.36.0.dist-info}/RECORD +8 -8
- {plain_jobs-0.35.0.dist-info → plain_jobs-0.36.0.dist-info}/WHEEL +0 -0
- {plain_jobs-0.35.0.dist-info → plain_jobs-0.36.0.dist-info}/licenses/LICENSE +0 -0
plain/jobs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# plain-jobs changelog
|
|
2
2
|
|
|
3
|
+
## [0.36.0](https://github.com/dropseed/plain/releases/plain-jobs@0.36.0) (2025-10-17)
|
|
4
|
+
|
|
5
|
+
### What's changed
|
|
6
|
+
|
|
7
|
+
- Removed internal memory optimization attempts including manual garbage collection and object deletion in worker processes ([c7064ba329](https://github.com/dropseed/plain/commit/c7064ba329))
|
|
8
|
+
- Increased worker sleep interval from 0.1s to 0.5s when no jobs are available, reducing CPU usage during idle periods ([c7064ba329](https://github.com/dropseed/plain/commit/c7064ba329))
|
|
9
|
+
|
|
10
|
+
### Upgrade instructions
|
|
11
|
+
|
|
12
|
+
- No changes required
|
|
13
|
+
|
|
14
|
+
## [0.35.1](https://github.com/dropseed/plain/releases/plain-jobs@0.35.1) (2025-10-17)
|
|
15
|
+
|
|
16
|
+
### What's changed
|
|
17
|
+
|
|
18
|
+
- The `run_in_worker()` method now returns `None` when a duplicate job is detected instead of attempting to return the list of in-progress jobs ([72f48d21bc](https://github.com/dropseed/plain/commit/72f48d21bc))
|
|
19
|
+
- Fixed type annotations for `run_in_worker()` to properly indicate it can return `JobRequest | None` ([72f48d21bc](https://github.com/dropseed/plain/commit/72f48d21bc))
|
|
20
|
+
- The `retry_job()` method now properly handles explicit `delay=0` parameter to intentionally retry immediately ([72f48d21bc](https://github.com/dropseed/plain/commit/72f48d21bc))
|
|
21
|
+
- Fixed type annotations for `retry_job()` to properly indicate it can return `JobRequest | None` ([72f48d21bc](https://github.com/dropseed/plain/commit/72f48d21bc))
|
|
22
|
+
|
|
23
|
+
### Upgrade instructions
|
|
24
|
+
|
|
25
|
+
- No changes required
|
|
26
|
+
|
|
3
27
|
## [0.35.0](https://github.com/dropseed/plain/releases/plain-jobs@0.35.0) (2025-10-17)
|
|
4
28
|
|
|
5
29
|
### What's changed
|
plain/jobs/jobs.py
CHANGED
|
@@ -62,7 +62,7 @@ class Job(metaclass=JobType):
|
|
|
62
62
|
retries: int | None = None,
|
|
63
63
|
retry_attempt: int = 0,
|
|
64
64
|
unique_key: str | None = None,
|
|
65
|
-
) -> JobRequest |
|
|
65
|
+
) -> JobRequest | None:
|
|
66
66
|
from .models import JobRequest
|
|
67
67
|
|
|
68
68
|
job_class_name = jobs_registry.get_job_class_name(self.__class__)
|
|
@@ -170,8 +170,7 @@ class Job(metaclass=JobType):
|
|
|
170
170
|
span.set_attribute(ERROR_TYPE, "IntegrityError")
|
|
171
171
|
span.set_status(trace.Status(trace.StatusCode.ERROR, "Duplicate job"))
|
|
172
172
|
logger.warning("Job already in progress: %s", e)
|
|
173
|
-
|
|
174
|
-
return self._in_progress(unique_key)
|
|
173
|
+
return None
|
|
175
174
|
|
|
176
175
|
def _in_progress(self, unique_key: str) -> list[JobRequest | JobProcess]:
|
|
177
176
|
"""Get all JobRequests and JobProcess that are currently in progress, regardless of queue."""
|
plain/jobs/models.py
CHANGED
|
@@ -412,10 +412,14 @@ class JobResult(models.Model):
|
|
|
412
412
|
],
|
|
413
413
|
)
|
|
414
414
|
|
|
415
|
-
def retry_job(self, delay: int | None = None) -> JobRequest:
|
|
415
|
+
def retry_job(self, delay: int | None = None) -> JobRequest | None:
|
|
416
416
|
retry_attempt = self.retry_attempt + 1
|
|
417
417
|
job = jobs_registry.load_job(self.job_class, self.parameters)
|
|
418
|
-
|
|
418
|
+
|
|
419
|
+
if delay is None:
|
|
420
|
+
retry_delay = job.get_retry_delay(retry_attempt)
|
|
421
|
+
else:
|
|
422
|
+
retry_delay = delay
|
|
419
423
|
|
|
420
424
|
with transaction.atomic():
|
|
421
425
|
result = job.run_in_worker(
|
|
@@ -427,12 +431,9 @@ class JobResult(models.Model):
|
|
|
427
431
|
retry_attempt=retry_attempt,
|
|
428
432
|
# Unique key could be passed also?
|
|
429
433
|
)
|
|
434
|
+
if result:
|
|
435
|
+
self.retry_job_request_uuid = result.uuid
|
|
436
|
+
self.save(update_fields=["retry_job_request_uuid"])
|
|
437
|
+
return result
|
|
430
438
|
|
|
431
|
-
|
|
432
|
-
# of pending jobs, which would need to be handled...
|
|
433
|
-
# Right now it will throw an exception which could be caught by retry_failed_jobs.
|
|
434
|
-
|
|
435
|
-
self.retry_job_request_uuid = result.uuid # type: ignore
|
|
436
|
-
self.save(update_fields=["retry_job_request_uuid"])
|
|
437
|
-
|
|
438
|
-
return result # type: ignore
|
|
439
|
+
return None
|
plain/jobs/workers.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import gc
|
|
4
3
|
import logging
|
|
5
4
|
import multiprocessing
|
|
6
5
|
import os
|
|
@@ -122,7 +121,7 @@ class Worker:
|
|
|
122
121
|
# We don't want to convert too many JobRequests to Jobs,
|
|
123
122
|
# because anything not started yet will be cancelled on deploy etc.
|
|
124
123
|
# It's easier to leave them in the JobRequest db queue as long as possible.
|
|
125
|
-
time.sleep(0.
|
|
124
|
+
time.sleep(0.5)
|
|
126
125
|
continue
|
|
127
126
|
|
|
128
127
|
with transaction.atomic():
|
|
@@ -157,19 +156,11 @@ class Worker:
|
|
|
157
156
|
|
|
158
157
|
job_process_uuid = str(job.uuid) # Make a str copy
|
|
159
158
|
|
|
160
|
-
# Release these now
|
|
161
|
-
del job_request
|
|
162
|
-
del job
|
|
163
|
-
|
|
164
159
|
future = self.executor.submit(process_job, job_process_uuid)
|
|
165
160
|
future.add_done_callback(
|
|
166
161
|
partial(future_finished_callback, job_process_uuid)
|
|
167
162
|
)
|
|
168
163
|
|
|
169
|
-
# Do a quick sleep regardless to see if it
|
|
170
|
-
# gives processes a chance to start up
|
|
171
|
-
time.sleep(0.1)
|
|
172
|
-
|
|
173
164
|
def shutdown(self) -> None:
|
|
174
165
|
if self._is_shutting_down:
|
|
175
166
|
# Already shutting down somewhere else
|
|
@@ -339,9 +330,6 @@ def process_job(job_process_uuid: str) -> None:
|
|
|
339
330
|
|
|
340
331
|
job_result = middleware_chain(job_process)
|
|
341
332
|
|
|
342
|
-
# Release it now
|
|
343
|
-
del job_process
|
|
344
|
-
|
|
345
333
|
duration = job_result.ended_at - job_result.started_at # type: ignore[unsupported-operator]
|
|
346
334
|
duration = duration.total_seconds()
|
|
347
335
|
|
|
@@ -357,8 +345,6 @@ def process_job(job_process_uuid: str) -> None:
|
|
|
357
345
|
job_result.queue,
|
|
358
346
|
duration,
|
|
359
347
|
)
|
|
360
|
-
|
|
361
|
-
del job_result
|
|
362
348
|
except Exception as e:
|
|
363
349
|
# Raising exceptions inside the worker process doesn't
|
|
364
350
|
# seem to be caught/shown anywhere as configured.
|
|
@@ -367,4 +353,3 @@ def process_job(job_process_uuid: str) -> None:
|
|
|
367
353
|
logger.exception(e)
|
|
368
354
|
finally:
|
|
369
355
|
request_finished.send(sender=None)
|
|
370
|
-
gc.collect()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
plain/jobs/CHANGELOG.md,sha256=
|
|
1
|
+
plain/jobs/CHANGELOG.md,sha256=9oOxk4cLHZAgsTxiv-vEifvNBuuXtxvMTA1SWnsb8JA,11847
|
|
2
2
|
plain/jobs/README.md,sha256=Xuhz2Q48G9WeGCh5OWGVBlaSea4eKCqWzcTAtZRrS0I,6835
|
|
3
3
|
plain/jobs/__init__.py,sha256=p2ATql3HyPzPTV34gJQ04caT7tcNQLbBGM6uIoDPbjo,92
|
|
4
4
|
plain/jobs/admin.py,sha256=t1UEchq1-Eews_wPsVUofaqbzPaYpb-8H1bUlA59JGI,6785
|
|
@@ -6,13 +6,13 @@ plain/jobs/chores.py,sha256=oyVU-BfcJxMM3eK2_umn38N2mBsNpcDrZfpeEQju_DA,528
|
|
|
6
6
|
plain/jobs/cli.py,sha256=PPoT7xjl818BZnmI0yA_UCLEQkzl_Tv1_hiuJW9UE-Q,5911
|
|
7
7
|
plain/jobs/config.py,sha256=PQsl-LxWsWLnjC98f0mvtdcCOuXvXKDMjrCRf1fq44Y,550
|
|
8
8
|
plain/jobs/default_settings.py,sha256=r_95ucg_KY1XW1jarZy8VO3p-ylbllKMUrHzOPJiX6U,227
|
|
9
|
-
plain/jobs/jobs.py,sha256=
|
|
9
|
+
plain/jobs/jobs.py,sha256=ZEne6eTVPoWBv-JUAB9GugdIR0pb2I5SDfJlxCrNI4c,7775
|
|
10
10
|
plain/jobs/middleware.py,sha256=bz8aPBY0RbtLS4kic8mzPOd3EyQFCVRQ2uTCttT3RpE,573
|
|
11
|
-
plain/jobs/models.py,sha256=
|
|
11
|
+
plain/jobs/models.py,sha256=TYOjMT0dSF69uzfY2m13ZPwo6G0WOVJUbgJvsDFxBhI,15889
|
|
12
12
|
plain/jobs/parameters.py,sha256=t9PwEZgwNCJx3YobsT-jfaVZdfMBS54XJcBrT9Wnsg0,6313
|
|
13
13
|
plain/jobs/registry.py,sha256=Rwn5Htll10e549vD2Mu0oyoDynyHhE0bGYZ2bq9uzPU,1679
|
|
14
14
|
plain/jobs/scheduling.py,sha256=fqpFnVoIIV-muf82WzuLyioSmiilfZ76KFjXzt8grIk,7851
|
|
15
|
-
plain/jobs/workers.py,sha256=
|
|
15
|
+
plain/jobs/workers.py,sha256=cHWxdAKbhyRACwRap7Eh1wfbOQzXLAl6o_8DR8zLA-Y,13546
|
|
16
16
|
plain/jobs/migrations/0001_initial.py,sha256=EIgIEMVyTsStyx9dmKM8Jb_hwn694Yo31-74DZkNTqo,9452
|
|
17
17
|
plain/jobs/migrations/0002_job_span_id_job_trace_id_jobrequest_span_id_and_more.py,sha256=ph5BwwOAwdfjdNh9RItYmX_IA29lO-Dd9GymYzvChXQ,1953
|
|
18
18
|
plain/jobs/migrations/0003_rename_job_jobprocess_and_more.py,sha256=EdLucHxiH_QshLL2peIcMULRCQyFMPxh476AxCxW5Wk,2615
|
|
@@ -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.36.0.dist-info/METADATA,sha256=Irv5tmv2qiqwrhw9T8w152bUCFSZA8lIOnma-AlvB5Q,7162
|
|
25
|
+
plain_jobs-0.36.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
26
|
+
plain_jobs-0.36.0.dist-info/licenses/LICENSE,sha256=cvKM3OlqHx3ijD6e34zsSUkPvzl-ya3Dd63A6EHL94U,1500
|
|
27
|
+
plain_jobs-0.36.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|