taskito 0.7.0__tar.gz → 0.9.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.
- {taskito-0.7.0 → taskito-0.9.0}/Cargo.lock +22 -3
- {taskito-0.7.0 → taskito-0.9.0}/PKG-INFO +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/Cargo.toml +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/scheduler/maintenance.rs +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/scheduler/mod.rs +15 -6
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/scheduler/poller.rs +4 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/diesel_common/jobs.rs +27 -5
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/mod.rs +53 -13
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/models.rs +11 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/archival.rs +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/dead_letter.rs +2 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/mod.rs +28 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/workers.rs +45 -5
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/dead_letter.rs +5 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/jobs.rs +39 -3
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/workers.rs +74 -14
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/schema.rs +6 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/archival.rs +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/dead_letter.rs +2 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/mod.rs +19 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/tests.rs +29 -17
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/workers.rs +45 -5
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/traits.rs +16 -3
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/tests/rust/storage_tests.rs +28 -8
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/Cargo.toml +4 -1
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/lib.rs +1 -0
- taskito-0.9.0/crates/taskito-python/src/prefork/child.rs +122 -0
- taskito-0.9.0/crates/taskito-python/src/prefork/dispatch.rs +32 -0
- taskito-0.9.0/crates/taskito-python/src/prefork/mod.rs +198 -0
- taskito-0.9.0/crates/taskito-python/src/prefork/protocol.rs +123 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_job.rs +3 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_queue/inspection.rs +10 -3
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_queue/mod.rs +6 -3
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_queue/worker.rs +51 -17
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/__init__.py +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/_taskito.pyi +8 -1
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/app.py +57 -2
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/mixins.py +127 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/context.py +19 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/fastapi.py +36 -4
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/events.py +3 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/mixins.py +19 -2
- taskito-0.9.0/py_src/taskito/prefork/__init__.py +20 -0
- taskito-0.9.0/py_src/taskito/prefork/__main__.py +6 -0
- taskito-0.9.0/py_src/taskito/prefork/child.py +196 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/result.py +95 -0
- {taskito-0.7.0 → taskito-0.9.0}/pyproject.toml +1 -1
- {taskito-0.7.0 → taskito-0.9.0}/Cargo.toml +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/LICENSE +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/README.md +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/error.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/job.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/lib.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/periodic.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/resilience/circuit_breaker.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/resilience/dlq.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/resilience/mod.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/resilience/rate_limiter.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/resilience/retry.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/scheduler/result_handler.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/diesel_common/locks.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/diesel_common/logs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/diesel_common/metrics.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/diesel_common/mod.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/circuit_breakers.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/jobs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/locks.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/logs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/metrics.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/periodic.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/queue_state.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/rate_limits.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/postgres/trait_impl.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/archival.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/circuit_breakers.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/locks.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/logs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/metrics.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/mod.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/periodic.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/queue_state.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/rate_limits.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/redis_backend/trait_impl.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/circuit_breakers.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/jobs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/locks.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/logs.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/metrics.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/periodic.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/queue_state.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/rate_limits.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/storage/sqlite/trait_impl.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/src/worker.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-core/tests/rust.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/async_worker.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_config.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/crates/taskito-python/src/py_worker.rs +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/context.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/executor.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/helpers.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/locks.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/async_support/result.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/canvas.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/cli.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/admin.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/apps.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/management/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/management/commands/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/management/commands/taskito_dashboard.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/management/commands/taskito_info.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/management/commands/taskito_worker.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/django/settings.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/flask.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/otel.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/prometheus.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/contrib/sentry.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/dashboard.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/exceptions.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/health.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/inject.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/built_in.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/converters.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/errors.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/interceptor.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/metrics.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/reconstruct.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/registry.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/strategy.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/interception/walker.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/locks.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/middleware.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/built_in.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handler.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/boto3_client.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/file.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/gcs_client.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/httpx_client.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/logger.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/handlers/requests_session.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/metrics.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/no_proxy.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/reconstruct.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/registry.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/schema.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/proxies/signing.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/py.typed +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/__init__.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/definition.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/frozen.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/graph.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/health.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/pool.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/runtime.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/thread_local.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/resources/toml_config.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/scaler.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/serializers.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/task.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/dashboard.css +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/dashboard.html +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/actions.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/app.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/chart.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/components.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/utils.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/templates/js/views.js +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/testing.py +0 -0
- {taskito-0.7.0 → taskito-0.9.0}/py_src/taskito/webhooks.py +0 -0
|
@@ -43,6 +43,12 @@ version = "1.5.0"
|
|
|
43
43
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
44
44
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
45
45
|
|
|
46
|
+
[[package]]
|
|
47
|
+
name = "base64"
|
|
48
|
+
version = "0.22.1"
|
|
49
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
50
|
+
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
51
|
+
|
|
46
52
|
[[package]]
|
|
47
53
|
name = "bitflags"
|
|
48
54
|
version = "2.11.0"
|
|
@@ -324,6 +330,16 @@ dependencies = [
|
|
|
324
330
|
"percent-encoding",
|
|
325
331
|
]
|
|
326
332
|
|
|
333
|
+
[[package]]
|
|
334
|
+
name = "gethostname"
|
|
335
|
+
version = "1.1.0"
|
|
336
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
337
|
+
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
|
338
|
+
dependencies = [
|
|
339
|
+
"rustix",
|
|
340
|
+
"windows-link",
|
|
341
|
+
]
|
|
342
|
+
|
|
327
343
|
[[package]]
|
|
328
344
|
name = "getrandom"
|
|
329
345
|
version = "0.2.17"
|
|
@@ -1201,7 +1217,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
|
1201
1217
|
|
|
1202
1218
|
[[package]]
|
|
1203
1219
|
name = "taskito-async"
|
|
1204
|
-
version = "0.
|
|
1220
|
+
version = "0.9.0"
|
|
1205
1221
|
dependencies = [
|
|
1206
1222
|
"async-trait",
|
|
1207
1223
|
"crossbeam-channel",
|
|
@@ -1213,7 +1229,7 @@ dependencies = [
|
|
|
1213
1229
|
|
|
1214
1230
|
[[package]]
|
|
1215
1231
|
name = "taskito-core"
|
|
1216
|
-
version = "0.
|
|
1232
|
+
version = "0.9.0"
|
|
1217
1233
|
dependencies = [
|
|
1218
1234
|
"async-trait",
|
|
1219
1235
|
"chrono",
|
|
@@ -1237,12 +1253,15 @@ dependencies = [
|
|
|
1237
1253
|
|
|
1238
1254
|
[[package]]
|
|
1239
1255
|
name = "taskito-python"
|
|
1240
|
-
version = "0.
|
|
1256
|
+
version = "0.9.0"
|
|
1241
1257
|
dependencies = [
|
|
1242
1258
|
"async-trait",
|
|
1259
|
+
"base64",
|
|
1243
1260
|
"crossbeam-channel",
|
|
1261
|
+
"gethostname",
|
|
1244
1262
|
"log",
|
|
1245
1263
|
"pyo3",
|
|
1264
|
+
"serde",
|
|
1246
1265
|
"serde_json",
|
|
1247
1266
|
"taskito-async",
|
|
1248
1267
|
"taskito-core",
|
|
@@ -128,6 +128,7 @@ pub struct Scheduler {
|
|
|
128
128
|
config: SchedulerConfig,
|
|
129
129
|
shutdown: Arc<Notify>,
|
|
130
130
|
paused_cache: Mutex<(HashSet<String>, Instant)>,
|
|
131
|
+
namespace: Option<String>,
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
/// Counters for tick-based scheduling of periodic maintenance tasks.
|
|
@@ -139,7 +140,12 @@ struct TickCounters {
|
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
impl Scheduler {
|
|
142
|
-
pub fn new(
|
|
143
|
+
pub fn new(
|
|
144
|
+
storage: StorageBackend,
|
|
145
|
+
queues: Vec<String>,
|
|
146
|
+
config: SchedulerConfig,
|
|
147
|
+
namespace: Option<String>,
|
|
148
|
+
) -> Self {
|
|
143
149
|
let rate_limiter = RateLimiter::new(storage.clone());
|
|
144
150
|
let dlq = DeadLetterQueue::new(storage.clone());
|
|
145
151
|
let circuit_breaker = CircuitBreaker::new(storage.clone());
|
|
@@ -155,6 +161,7 @@ impl Scheduler {
|
|
|
155
161
|
config,
|
|
156
162
|
shutdown: Arc::new(Notify::new()),
|
|
157
163
|
paused_cache: Mutex::new((HashSet::new(), Instant::now())),
|
|
164
|
+
namespace,
|
|
158
165
|
}
|
|
159
166
|
}
|
|
160
167
|
|
|
@@ -249,6 +256,7 @@ mod tests {
|
|
|
249
256
|
storage,
|
|
250
257
|
vec!["default".to_string()],
|
|
251
258
|
SchedulerConfig::default(),
|
|
259
|
+
None,
|
|
252
260
|
)
|
|
253
261
|
}
|
|
254
262
|
|
|
@@ -445,7 +453,7 @@ mod tests {
|
|
|
445
453
|
// The second job should be back in pending with a future scheduled_at
|
|
446
454
|
let jobs = scheduler
|
|
447
455
|
.storage
|
|
448
|
-
.list_jobs(Some(JobStatus::Pending as i32), None, None, 10, 0)
|
|
456
|
+
.list_jobs(Some(JobStatus::Pending as i32), None, None, 10, 0, None)
|
|
449
457
|
.unwrap();
|
|
450
458
|
assert_eq!(jobs.len(), 1);
|
|
451
459
|
assert!(jobs[0].scheduled_at > now_millis());
|
|
@@ -486,7 +494,7 @@ mod tests {
|
|
|
486
494
|
// Job should be rescheduled
|
|
487
495
|
let jobs = scheduler
|
|
488
496
|
.storage
|
|
489
|
-
.list_jobs(Some(JobStatus::Pending as i32), None, None, 10, 0)
|
|
497
|
+
.list_jobs(Some(JobStatus::Pending as i32), None, None, 10, 0, None)
|
|
490
498
|
.unwrap();
|
|
491
499
|
assert_eq!(jobs.len(), 1);
|
|
492
500
|
assert!(jobs[0].scheduled_at > now_millis());
|
|
@@ -562,6 +570,7 @@ mod tests {
|
|
|
562
570
|
Some("periodic_task"),
|
|
563
571
|
10,
|
|
564
572
|
0,
|
|
573
|
+
None,
|
|
565
574
|
)
|
|
566
575
|
.unwrap();
|
|
567
576
|
assert_eq!(jobs.len(), 1);
|
|
@@ -575,13 +584,13 @@ mod tests {
|
|
|
575
584
|
result_ttl_ms: Some(1), // 1ms TTL
|
|
576
585
|
..SchedulerConfig::default()
|
|
577
586
|
};
|
|
578
|
-
let scheduler = Scheduler::new(storage, vec!["default".to_string()], config);
|
|
587
|
+
let scheduler = Scheduler::new(storage, vec!["default".to_string()], config, None);
|
|
579
588
|
|
|
580
589
|
// Enqueue, dequeue, and complete a job
|
|
581
590
|
let job = scheduler.storage.enqueue(make_job("cleanup_task")).unwrap();
|
|
582
591
|
scheduler
|
|
583
592
|
.storage
|
|
584
|
-
.dequeue("default", now_millis() + 1000)
|
|
593
|
+
.dequeue("default", now_millis() + 1000, None)
|
|
585
594
|
.unwrap();
|
|
586
595
|
scheduler.storage.complete(&job.id, Some(vec![1])).unwrap();
|
|
587
596
|
|
|
@@ -605,7 +614,7 @@ mod tests {
|
|
|
605
614
|
cleanup_interval: 1,
|
|
606
615
|
..SchedulerConfig::default()
|
|
607
616
|
};
|
|
608
|
-
let scheduler = Scheduler::new(storage, vec!["default".to_string()], config);
|
|
617
|
+
let scheduler = Scheduler::new(storage, vec!["default".to_string()], config, None);
|
|
609
618
|
|
|
610
619
|
scheduler.storage.enqueue(make_job("tick_task")).unwrap();
|
|
611
620
|
|
|
@@ -51,7 +51,10 @@ impl Scheduler {
|
|
|
51
51
|
return Ok(false);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
let job = match self
|
|
54
|
+
let job = match self
|
|
55
|
+
.storage
|
|
56
|
+
.dequeue_from(&active_queues, now, self.namespace.as_deref())?
|
|
57
|
+
{
|
|
55
58
|
Some(j) => j,
|
|
56
59
|
None => return Ok(false),
|
|
57
60
|
};
|
|
@@ -270,17 +270,27 @@ macro_rules! impl_diesel_job_ops {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
/// Atomically dequeue the highest-priority ready job from the given queue.
|
|
273
|
-
/// Skips expired jobs.
|
|
274
|
-
|
|
273
|
+
/// Skips expired jobs. When `namespace` is `Some`, only jobs in that
|
|
274
|
+
/// namespace are considered; when `None`, only jobs with no namespace.
|
|
275
|
+
pub fn dequeue(&self, queue_name: &str, now: i64, namespace: Option<&str>) -> Result<Option<Job>> {
|
|
275
276
|
let mut conn = self.conn()?;
|
|
276
277
|
|
|
277
278
|
conn.transaction(|conn| {
|
|
278
|
-
let
|
|
279
|
+
let mut query = jobs::table
|
|
279
280
|
.filter(jobs::queue.eq(queue_name))
|
|
280
281
|
.filter(jobs::status.eq(JobStatus::Pending as i32))
|
|
281
282
|
.filter(jobs::scheduled_at.le(now))
|
|
282
283
|
.order((jobs::priority.desc(), jobs::scheduled_at.asc()))
|
|
283
284
|
.limit(100)
|
|
285
|
+
.into_boxed();
|
|
286
|
+
|
|
287
|
+
if let Some(ns) = namespace {
|
|
288
|
+
query = query.filter(jobs::namespace.eq(ns));
|
|
289
|
+
} else {
|
|
290
|
+
query = query.filter(jobs::namespace.is_null());
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let candidates: Vec<JobRow> = query
|
|
284
294
|
.select(JobRow::as_select())
|
|
285
295
|
.load(conn)?;
|
|
286
296
|
|
|
@@ -327,9 +337,9 @@ macro_rules! impl_diesel_job_ops {
|
|
|
327
337
|
}
|
|
328
338
|
|
|
329
339
|
/// Dequeue from multiple queues, checking each in order.
|
|
330
|
-
pub fn dequeue_from(&self, queues: &[String], now: i64) -> Result<Option<Job>> {
|
|
340
|
+
pub fn dequeue_from(&self, queues: &[String], now: i64, namespace: Option<&str>) -> Result<Option<Job>> {
|
|
331
341
|
for queue_name in queues {
|
|
332
|
-
if let Some(job) = self.dequeue(queue_name, now)? {
|
|
342
|
+
if let Some(job) = self.dequeue(queue_name, now, namespace)? {
|
|
333
343
|
return Ok(Some(job));
|
|
334
344
|
}
|
|
335
345
|
}
|
|
@@ -554,6 +564,8 @@ macro_rules! impl_diesel_job_ops {
|
|
|
554
564
|
}
|
|
555
565
|
|
|
556
566
|
/// List jobs with optional filters and pagination.
|
|
567
|
+
/// When `namespace` is `Some`, only jobs in that namespace are returned.
|
|
568
|
+
/// When `None`, all jobs are returned regardless of namespace.
|
|
557
569
|
pub fn list_jobs(
|
|
558
570
|
&self,
|
|
559
571
|
status: Option<i32>,
|
|
@@ -561,6 +573,7 @@ macro_rules! impl_diesel_job_ops {
|
|
|
561
573
|
task_name: Option<&str>,
|
|
562
574
|
limit: i64,
|
|
563
575
|
offset: i64,
|
|
576
|
+
namespace: Option<&str>,
|
|
564
577
|
) -> Result<Vec<Job>> {
|
|
565
578
|
let mut conn = self.conn()?;
|
|
566
579
|
|
|
@@ -575,6 +588,9 @@ macro_rules! impl_diesel_job_ops {
|
|
|
575
588
|
if let Some(t) = task_name {
|
|
576
589
|
query = query.filter(jobs::task_name.eq(t));
|
|
577
590
|
}
|
|
591
|
+
if let Some(ns) = namespace {
|
|
592
|
+
query = query.filter(jobs::namespace.eq(ns));
|
|
593
|
+
}
|
|
578
594
|
|
|
579
595
|
let rows: Vec<JobRow> = query
|
|
580
596
|
.limit(limit)
|
|
@@ -678,6 +694,8 @@ macro_rules! impl_diesel_job_ops {
|
|
|
678
694
|
}
|
|
679
695
|
|
|
680
696
|
/// List jobs with extended filters.
|
|
697
|
+
/// When `namespace` is `Some`, only jobs in that namespace are returned.
|
|
698
|
+
/// When `None`, all jobs are returned regardless of namespace.
|
|
681
699
|
#[allow(clippy::too_many_arguments)]
|
|
682
700
|
pub fn list_jobs_filtered(
|
|
683
701
|
&self,
|
|
@@ -690,6 +708,7 @@ macro_rules! impl_diesel_job_ops {
|
|
|
690
708
|
created_before: Option<i64>,
|
|
691
709
|
limit: i64,
|
|
692
710
|
offset: i64,
|
|
711
|
+
namespace: Option<&str>,
|
|
693
712
|
) -> Result<Vec<Job>> {
|
|
694
713
|
let mut conn = self.conn()?;
|
|
695
714
|
|
|
@@ -716,6 +735,9 @@ macro_rules! impl_diesel_job_ops {
|
|
|
716
735
|
if let Some(before) = created_before {
|
|
717
736
|
query = query.filter(jobs::created_at.le(before));
|
|
718
737
|
}
|
|
738
|
+
if let Some(ns) = namespace {
|
|
739
|
+
query = query.filter(jobs::namespace.eq(ns));
|
|
740
|
+
}
|
|
719
741
|
|
|
720
742
|
let rows: Vec<JobRow> = query
|
|
721
743
|
.limit(limit)
|
|
@@ -40,6 +40,7 @@ pub struct DeadJob {
|
|
|
40
40
|
pub max_retries: i32,
|
|
41
41
|
pub timeout_ms: i64,
|
|
42
42
|
pub result_ttl_ms: Option<i64>,
|
|
43
|
+
pub namespace: Option<String>,
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
impl From<models::DeadLetterRow> for DeadJob {
|
|
@@ -58,6 +59,7 @@ impl From<models::DeadLetterRow> for DeadJob {
|
|
|
58
59
|
max_retries: row.max_retries,
|
|
59
60
|
timeout_ms: row.timeout_ms,
|
|
60
61
|
result_ttl_ms: row.result_ttl_ms,
|
|
62
|
+
namespace: row.namespace,
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
}
|
|
@@ -93,15 +95,17 @@ macro_rules! impl_storage {
|
|
|
93
95
|
&self,
|
|
94
96
|
queue_name: &str,
|
|
95
97
|
now: i64,
|
|
98
|
+
namespace: Option<&str>,
|
|
96
99
|
) -> $crate::error::Result<Option<$crate::job::Job>> {
|
|
97
|
-
self.dequeue(queue_name, now)
|
|
100
|
+
self.dequeue(queue_name, now, namespace)
|
|
98
101
|
}
|
|
99
102
|
fn dequeue_from(
|
|
100
103
|
&self,
|
|
101
104
|
queues: &[String],
|
|
102
105
|
now: i64,
|
|
106
|
+
namespace: Option<&str>,
|
|
103
107
|
) -> $crate::error::Result<Option<$crate::job::Job>> {
|
|
104
|
-
self.dequeue_from(queues, now)
|
|
108
|
+
self.dequeue_from(queues, now, namespace)
|
|
105
109
|
}
|
|
106
110
|
fn complete(
|
|
107
111
|
&self,
|
|
@@ -151,8 +155,9 @@ macro_rules! impl_storage {
|
|
|
151
155
|
task_name: Option<&str>,
|
|
152
156
|
limit: i64,
|
|
153
157
|
offset: i64,
|
|
158
|
+
namespace: Option<&str>,
|
|
154
159
|
) -> $crate::error::Result<Vec<$crate::job::Job>> {
|
|
155
|
-
self.list_jobs(status, queue_name, task_name, limit, offset)
|
|
160
|
+
self.list_jobs(status, queue_name, task_name, limit, offset, namespace)
|
|
156
161
|
}
|
|
157
162
|
fn get_job(&self, id: &str) -> $crate::error::Result<Option<$crate::job::Job>> {
|
|
158
163
|
self.get_job(id)
|
|
@@ -347,8 +352,11 @@ macro_rules! impl_storage {
|
|
|
347
352
|
resources: Option<&str>,
|
|
348
353
|
resource_health: Option<&str>,
|
|
349
354
|
threads: i32,
|
|
355
|
+
hostname: Option<&str>,
|
|
356
|
+
pid: Option<i32>,
|
|
357
|
+
pool_type: Option<&str>,
|
|
350
358
|
) -> $crate::error::Result<()> {
|
|
351
|
-
self.register_worker(worker_id, queues, tags, resources, resource_health, threads)
|
|
359
|
+
self.register_worker(worker_id, queues, tags, resources, resource_health, threads, hostname, pid, pool_type)
|
|
352
360
|
}
|
|
353
361
|
fn heartbeat(
|
|
354
362
|
&self,
|
|
@@ -357,17 +365,27 @@ macro_rules! impl_storage {
|
|
|
357
365
|
) -> $crate::error::Result<()> {
|
|
358
366
|
self.heartbeat(worker_id, resource_health)
|
|
359
367
|
}
|
|
368
|
+
fn update_worker_status(
|
|
369
|
+
&self,
|
|
370
|
+
worker_id: &str,
|
|
371
|
+
status: &str,
|
|
372
|
+
) -> $crate::error::Result<()> {
|
|
373
|
+
self.update_worker_status(worker_id, status)
|
|
374
|
+
}
|
|
360
375
|
fn list_workers(
|
|
361
376
|
&self,
|
|
362
377
|
) -> $crate::error::Result<Vec<$crate::storage::models::WorkerRow>> {
|
|
363
378
|
self.list_workers()
|
|
364
379
|
}
|
|
365
|
-
fn reap_dead_workers(&self) -> $crate::error::Result<
|
|
380
|
+
fn reap_dead_workers(&self) -> $crate::error::Result<Vec<String>> {
|
|
366
381
|
self.reap_dead_workers()
|
|
367
382
|
}
|
|
368
383
|
fn unregister_worker(&self, worker_id: &str) -> $crate::error::Result<()> {
|
|
369
384
|
self.unregister_worker(worker_id)
|
|
370
385
|
}
|
|
386
|
+
fn list_claims_by_worker(&self, worker_id: &str) -> $crate::error::Result<Vec<String>> {
|
|
387
|
+
self.list_claims_by_worker(worker_id)
|
|
388
|
+
}
|
|
371
389
|
fn pause_queue(&self, queue_name: &str) -> $crate::error::Result<()> {
|
|
372
390
|
self.pause_queue(queue_name)
|
|
373
391
|
}
|
|
@@ -473,6 +491,7 @@ macro_rules! impl_storage {
|
|
|
473
491
|
created_before: Option<i64>,
|
|
474
492
|
limit: i64,
|
|
475
493
|
offset: i64,
|
|
494
|
+
namespace: Option<&str>,
|
|
476
495
|
) -> $crate::error::Result<Vec<$crate::job::Job>> {
|
|
477
496
|
self.list_jobs_filtered(
|
|
478
497
|
status,
|
|
@@ -484,6 +503,7 @@ macro_rules! impl_storage {
|
|
|
484
503
|
created_before,
|
|
485
504
|
limit,
|
|
486
505
|
offset,
|
|
506
|
+
namespace,
|
|
487
507
|
)
|
|
488
508
|
}
|
|
489
509
|
}
|
|
@@ -526,11 +546,16 @@ impl Storage for StorageBackend {
|
|
|
526
546
|
fn enqueue_unique(&self, new_job: NewJob) -> Result<Job> {
|
|
527
547
|
delegate!(self, enqueue_unique, new_job)
|
|
528
548
|
}
|
|
529
|
-
fn dequeue(&self, queue_name: &str, now: i64) -> Result<Option<Job>> {
|
|
530
|
-
delegate!(self, dequeue, queue_name, now)
|
|
549
|
+
fn dequeue(&self, queue_name: &str, now: i64, namespace: Option<&str>) -> Result<Option<Job>> {
|
|
550
|
+
delegate!(self, dequeue, queue_name, now, namespace)
|
|
531
551
|
}
|
|
532
|
-
fn dequeue_from(
|
|
533
|
-
|
|
552
|
+
fn dequeue_from(
|
|
553
|
+
&self,
|
|
554
|
+
queues: &[String],
|
|
555
|
+
now: i64,
|
|
556
|
+
namespace: Option<&str>,
|
|
557
|
+
) -> Result<Option<Job>> {
|
|
558
|
+
delegate!(self, dequeue_from, queues, now, namespace)
|
|
534
559
|
}
|
|
535
560
|
fn complete(&self, id: &str, result_bytes: Option<Vec<u8>>) -> Result<()> {
|
|
536
561
|
delegate!(self, complete, id, result_bytes)
|
|
@@ -572,8 +597,9 @@ impl Storage for StorageBackend {
|
|
|
572
597
|
task_name: Option<&str>,
|
|
573
598
|
limit: i64,
|
|
574
599
|
offset: i64,
|
|
600
|
+
namespace: Option<&str>,
|
|
575
601
|
) -> Result<Vec<Job>> {
|
|
576
|
-
delegate!(self, list_jobs, status, queue_name, task_name, limit, offset)
|
|
602
|
+
delegate!(self, list_jobs, status, queue_name, task_name, limit, offset, namespace)
|
|
577
603
|
}
|
|
578
604
|
fn get_job(&self, id: &str) -> Result<Option<Job>> {
|
|
579
605
|
delegate!(self, get_job, id)
|
|
@@ -726,6 +752,9 @@ impl Storage for StorageBackend {
|
|
|
726
752
|
resources: Option<&str>,
|
|
727
753
|
resource_health: Option<&str>,
|
|
728
754
|
threads: i32,
|
|
755
|
+
hostname: Option<&str>,
|
|
756
|
+
pid: Option<i32>,
|
|
757
|
+
pool_type: Option<&str>,
|
|
729
758
|
) -> Result<()> {
|
|
730
759
|
delegate!(
|
|
731
760
|
self,
|
|
@@ -735,21 +764,30 @@ impl Storage for StorageBackend {
|
|
|
735
764
|
tags,
|
|
736
765
|
resources,
|
|
737
766
|
resource_health,
|
|
738
|
-
threads
|
|
767
|
+
threads,
|
|
768
|
+
hostname,
|
|
769
|
+
pid,
|
|
770
|
+
pool_type
|
|
739
771
|
)
|
|
740
772
|
}
|
|
741
773
|
fn heartbeat(&self, worker_id: &str, resource_health: Option<&str>) -> Result<()> {
|
|
742
774
|
delegate!(self, heartbeat, worker_id, resource_health)
|
|
743
775
|
}
|
|
776
|
+
fn update_worker_status(&self, worker_id: &str, status: &str) -> Result<()> {
|
|
777
|
+
delegate!(self, update_worker_status, worker_id, status)
|
|
778
|
+
}
|
|
744
779
|
fn list_workers(&self) -> Result<Vec<models::WorkerRow>> {
|
|
745
780
|
delegate!(self, list_workers)
|
|
746
781
|
}
|
|
747
|
-
fn reap_dead_workers(&self) -> Result<
|
|
782
|
+
fn reap_dead_workers(&self) -> Result<Vec<String>> {
|
|
748
783
|
delegate!(self, reap_dead_workers)
|
|
749
784
|
}
|
|
750
785
|
fn unregister_worker(&self, worker_id: &str) -> Result<()> {
|
|
751
786
|
delegate!(self, unregister_worker, worker_id)
|
|
752
787
|
}
|
|
788
|
+
fn list_claims_by_worker(&self, worker_id: &str) -> Result<Vec<String>> {
|
|
789
|
+
delegate!(self, list_claims_by_worker, worker_id)
|
|
790
|
+
}
|
|
753
791
|
fn pause_queue(&self, queue_name: &str) -> Result<()> {
|
|
754
792
|
delegate!(self, pause_queue, queue_name)
|
|
755
793
|
}
|
|
@@ -818,6 +856,7 @@ impl Storage for StorageBackend {
|
|
|
818
856
|
created_before: Option<i64>,
|
|
819
857
|
limit: i64,
|
|
820
858
|
offset: i64,
|
|
859
|
+
namespace: Option<&str>,
|
|
821
860
|
) -> Result<Vec<Job>> {
|
|
822
861
|
delegate!(
|
|
823
862
|
self,
|
|
@@ -830,7 +869,8 @@ impl Storage for StorageBackend {
|
|
|
830
869
|
created_after,
|
|
831
870
|
created_before,
|
|
832
871
|
limit,
|
|
833
|
-
offset
|
|
872
|
+
offset,
|
|
873
|
+
namespace
|
|
834
874
|
)
|
|
835
875
|
}
|
|
836
876
|
}
|
|
@@ -75,6 +75,7 @@ pub struct DeadLetterRow {
|
|
|
75
75
|
pub max_retries: i32,
|
|
76
76
|
pub timeout_ms: i64,
|
|
77
77
|
pub result_ttl_ms: Option<i64>,
|
|
78
|
+
pub namespace: Option<String>,
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
/// Insertable struct for dead letter entries.
|
|
@@ -94,6 +95,7 @@ pub struct NewDeadLetterRow<'a> {
|
|
|
94
95
|
pub max_retries: i32,
|
|
95
96
|
pub timeout_ms: i64,
|
|
96
97
|
pub result_ttl_ms: Option<i64>,
|
|
98
|
+
pub namespace: Option<&'a str>,
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
/// A row in the `rate_limits` table.
|
|
@@ -305,6 +307,10 @@ pub struct WorkerRow {
|
|
|
305
307
|
pub resources: Option<String>,
|
|
306
308
|
pub resource_health: Option<String>,
|
|
307
309
|
pub threads: i32,
|
|
310
|
+
pub started_at: Option<i64>,
|
|
311
|
+
pub hostname: Option<String>,
|
|
312
|
+
pub pid: Option<i32>,
|
|
313
|
+
pub pool_type: Option<String>,
|
|
308
314
|
}
|
|
309
315
|
|
|
310
316
|
#[derive(Insertable, AsChangeset, Debug)]
|
|
@@ -318,6 +324,10 @@ pub struct NewWorkerRow<'a> {
|
|
|
318
324
|
pub resources: Option<&'a str>,
|
|
319
325
|
pub resource_health: Option<&'a str>,
|
|
320
326
|
pub threads: i32,
|
|
327
|
+
pub started_at: Option<i64>,
|
|
328
|
+
pub hostname: Option<&'a str>,
|
|
329
|
+
pub pid: Option<i32>,
|
|
330
|
+
pub pool_type: Option<&'a str>,
|
|
321
331
|
}
|
|
322
332
|
|
|
323
333
|
// ── Queue State ─────────────────────────────────────────────────
|
|
@@ -394,4 +404,5 @@ pub struct ArchivedJobRow {
|
|
|
394
404
|
pub cancel_requested: i32,
|
|
395
405
|
pub expires_at: Option<i64>,
|
|
396
406
|
pub result_ttl_ms: Option<i64>,
|
|
407
|
+
pub namespace: Option<String>,
|
|
397
408
|
}
|
|
@@ -30,6 +30,7 @@ impl PostgresStorage {
|
|
|
30
30
|
max_retries: job.max_retries,
|
|
31
31
|
timeout_ms: job.timeout_ms,
|
|
32
32
|
result_ttl_ms: job.result_ttl_ms,
|
|
33
|
+
namespace: job.namespace.as_deref(),
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
diesel::insert_into(dead_letter::table)
|
|
@@ -94,7 +95,7 @@ impl PostgresStorage {
|
|
|
94
95
|
depends_on: vec![],
|
|
95
96
|
expires_at: None,
|
|
96
97
|
result_ttl_ms: dead_row.result_ttl_ms,
|
|
97
|
-
namespace:
|
|
98
|
+
namespace: dead_row.namespace,
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
let job = new_job.into_job();
|
|
@@ -359,6 +359,24 @@ impl PostgresStorage {
|
|
|
359
359
|
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS threads INTEGER NOT NULL DEFAULT 0",
|
|
360
360
|
);
|
|
361
361
|
|
|
362
|
+
// Migration: add worker discovery metadata columns
|
|
363
|
+
migration_alter(
|
|
364
|
+
&mut conn,
|
|
365
|
+
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS started_at BIGINT",
|
|
366
|
+
);
|
|
367
|
+
migration_alter(
|
|
368
|
+
&mut conn,
|
|
369
|
+
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS hostname TEXT",
|
|
370
|
+
);
|
|
371
|
+
migration_alter(
|
|
372
|
+
&mut conn,
|
|
373
|
+
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS pid INTEGER",
|
|
374
|
+
);
|
|
375
|
+
migration_alter(
|
|
376
|
+
&mut conn,
|
|
377
|
+
"ALTER TABLE workers ADD COLUMN IF NOT EXISTS pool_type TEXT",
|
|
378
|
+
);
|
|
379
|
+
|
|
362
380
|
diesel::sql_query(
|
|
363
381
|
"CREATE TABLE IF NOT EXISTS queue_state (
|
|
364
382
|
queue_name TEXT PRIMARY KEY,
|
|
@@ -434,6 +452,16 @@ impl PostgresStorage {
|
|
|
434
452
|
"ALTER TABLE circuit_breakers ADD COLUMN IF NOT EXISTS half_open_failure_count INTEGER NOT NULL DEFAULT 0",
|
|
435
453
|
);
|
|
436
454
|
|
|
455
|
+
// Migration: add namespace column to dead_letter and archived_jobs
|
|
456
|
+
migration_alter(
|
|
457
|
+
&mut conn,
|
|
458
|
+
"ALTER TABLE dead_letter ADD COLUMN IF NOT EXISTS namespace TEXT",
|
|
459
|
+
);
|
|
460
|
+
migration_alter(
|
|
461
|
+
&mut conn,
|
|
462
|
+
"ALTER TABLE archived_jobs ADD COLUMN IF NOT EXISTS namespace TEXT",
|
|
463
|
+
);
|
|
464
|
+
|
|
437
465
|
// ── Distributed Locks ─────────────────────────────
|
|
438
466
|
diesel::sql_query(
|
|
439
467
|
"CREATE TABLE IF NOT EXISTS distributed_locks (
|