taskito 0.2.2__tar.gz → 0.2.3__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.
Files changed (78) hide show
  1. {taskito-0.2.2 → taskito-0.2.3}/Cargo.lock +45 -2
  2. {taskito-0.2.2 → taskito-0.2.3}/Cargo.toml +1 -0
  3. {taskito-0.2.2 → taskito-0.2.3}/PKG-INFO +11 -5
  4. {taskito-0.2.2 → taskito-0.2.3}/README.md +7 -4
  5. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/Cargo.toml +6 -1
  6. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/job.rs +2 -2
  7. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/lib.rs +6 -3
  8. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/periodic.rs +3 -5
  9. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/resilience/circuit_breaker.rs +3 -3
  10. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/resilience/dlq.rs +3 -3
  11. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/resilience/rate_limiter.rs +9 -6
  12. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/resilience/retry.rs +2 -2
  13. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/scheduler.rs +182 -118
  14. taskito-0.2.3/crates/taskito-core/src/storage/mod.rs +299 -0
  15. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/models.rs +8 -0
  16. taskito-0.2.3/crates/taskito-core/src/storage/postgres/circuit_breakers.rs +40 -0
  17. taskito-0.2.3/crates/taskito-core/src/storage/postgres/dead_letter.rs +143 -0
  18. taskito-0.2.3/crates/taskito-core/src/storage/postgres/jobs.rs +739 -0
  19. taskito-0.2.3/crates/taskito-core/src/storage/postgres/logs.rs +89 -0
  20. taskito-0.2.3/crates/taskito-core/src/storage/postgres/metrics.rs +115 -0
  21. taskito-0.2.3/crates/taskito-core/src/storage/postgres/mod.rs +330 -0
  22. taskito-0.2.3/crates/taskito-core/src/storage/postgres/periodic.rs +49 -0
  23. taskito-0.2.3/crates/taskito-core/src/storage/postgres/rate_limits.rs +85 -0
  24. taskito-0.2.3/crates/taskito-core/src/storage/postgres/trait_impl.rs +207 -0
  25. taskito-0.2.3/crates/taskito-core/src/storage/postgres/workers.rs +79 -0
  26. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/schema.rs +4 -0
  27. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/dead_letter.rs +45 -18
  28. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/jobs.rs +166 -92
  29. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/logs.rs +5 -5
  30. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/metrics.rs +5 -5
  31. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/mod.rs +95 -101
  32. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/periodic.rs +2 -7
  33. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/rate_limits.rs +3 -8
  34. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/tests.rs +22 -9
  35. taskito-0.2.3/crates/taskito-core/src/storage/sqlite/trait_impl.rs +207 -0
  36. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/workers.rs +4 -5
  37. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/traits.rs +5 -3
  38. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/Cargo.toml +5 -1
  39. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/src/py_config.rs +1 -0
  40. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/src/py_queue.rs +77 -22
  41. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/src/py_worker.rs +33 -34
  42. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/__init__.py +6 -1
  43. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/_taskito.pyi +3 -0
  44. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/app.py +62 -10
  45. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/canvas.py +1 -1
  46. taskito-0.2.3/py_src/taskito/contrib/django/__init__.py +25 -0
  47. taskito-0.2.3/py_src/taskito/contrib/django/admin.py +176 -0
  48. taskito-0.2.3/py_src/taskito/contrib/django/apps.py +24 -0
  49. taskito-0.2.3/py_src/taskito/contrib/django/management/commands/__init__.py +0 -0
  50. taskito-0.2.3/py_src/taskito/contrib/django/management/commands/taskito_dashboard.py +27 -0
  51. taskito-0.2.3/py_src/taskito/contrib/django/management/commands/taskito_info.py +62 -0
  52. taskito-0.2.3/py_src/taskito/contrib/django/management/commands/taskito_worker.py +29 -0
  53. taskito-0.2.3/py_src/taskito/contrib/django/settings.py +38 -0
  54. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/contrib/otel.py +9 -3
  55. taskito-0.2.3/py_src/taskito/py.typed +0 -0
  56. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/result.py +1 -3
  57. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/testing.py +3 -0
  58. {taskito-0.2.2 → taskito-0.2.3}/pyproject.toml +7 -1
  59. taskito-0.2.2/crates/taskito-core/src/storage/mod.rs +0 -6
  60. taskito-0.2.2/crates/taskito-core/src/storage/sqlite/trait_impl.rs +0 -68
  61. {taskito-0.2.2 → taskito-0.2.3}/LICENSE +0 -0
  62. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/error.rs +0 -0
  63. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/resilience/mod.rs +0 -0
  64. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-core/src/storage/sqlite/circuit_breakers.rs +1 -1
  65. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/src/lib.rs +4 -4
  66. {taskito-0.2.2 → taskito-0.2.3}/crates/taskito-python/src/py_job.rs +0 -0
  67. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/cli.py +0 -0
  68. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/context.py +0 -0
  69. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/contrib/__init__.py +0 -0
  70. taskito-0.2.2/py_src/taskito/py.typed → taskito-0.2.3/py_src/taskito/contrib/django/management/__init__.py +0 -0
  71. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/contrib/fastapi.py +0 -0
  72. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/dashboard.py +6 -6
  73. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/exceptions.py +0 -0
  74. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/middleware.py +0 -0
  75. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/mixins.py +0 -0
  76. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/serializers.py +0 -0
  77. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/task.py +0 -0
  78. {taskito-0.2.2 → taskito-0.2.3}/py_src/taskito/templates/dashboard.html +0 -0
@@ -35,6 +35,12 @@ version = "3.20.2"
35
35
  source = "registry+https://github.com/rust-lang/crates.io-index"
36
36
  checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
37
37
 
38
+ [[package]]
39
+ name = "byteorder"
40
+ version = "1.5.0"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
43
+
38
44
  [[package]]
39
45
  name = "bytes"
40
46
  version = "1.11.1"
@@ -152,9 +158,13 @@ version = "2.3.6"
152
158
  source = "registry+https://github.com/rust-lang/crates.io-index"
153
159
  checksum = "d9b6c2fc184a6fb6ebcf5f9a5e3bbfa84d8fd268cdfcce4ed508979a6259494d"
154
160
  dependencies = [
161
+ "bitflags",
162
+ "byteorder",
155
163
  "diesel_derives",
156
164
  "downcast-rs",
165
+ "itoa",
157
166
  "libsqlite3-sys",
167
+ "pq-sys",
158
168
  "r2d2",
159
169
  "sqlite-wasm-rs",
160
170
  "time",
@@ -482,6 +492,18 @@ version = "1.21.3"
482
492
  source = "registry+https://github.com/rust-lang/crates.io-index"
483
493
  checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
484
494
 
495
+ [[package]]
496
+ name = "openssl-sys"
497
+ version = "0.9.111"
498
+ source = "registry+https://github.com/rust-lang/crates.io-index"
499
+ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
500
+ dependencies = [
501
+ "cc",
502
+ "libc",
503
+ "pkg-config",
504
+ "vcpkg",
505
+ ]
506
+
485
507
  [[package]]
486
508
  name = "parking_lot"
487
509
  version = "0.12.5"
@@ -538,6 +560,26 @@ dependencies = [
538
560
  "zerocopy",
539
561
  ]
540
562
 
563
+ [[package]]
564
+ name = "pq-src"
565
+ version = "0.3.11+libpq-18.3"
566
+ source = "registry+https://github.com/rust-lang/crates.io-index"
567
+ checksum = "6fb5bfbe0c3445d371dd8acf7d6c912ece8baf2f61f7c571af85a1d7687c2d0f"
568
+ dependencies = [
569
+ "cc",
570
+ "openssl-sys",
571
+ ]
572
+
573
+ [[package]]
574
+ name = "pq-sys"
575
+ version = "0.6.3"
576
+ source = "registry+https://github.com/rust-lang/crates.io-index"
577
+ checksum = "f6cc05d7ea95200187117196eee9edd0644424911821aeb28a18ce60ea0b8793"
578
+ dependencies = [
579
+ "pq-src",
580
+ "vcpkg",
581
+ ]
582
+
541
583
  [[package]]
542
584
  name = "prettyplease"
543
585
  version = "0.2.37"
@@ -847,7 +889,7 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
847
889
 
848
890
  [[package]]
849
891
  name = "taskito-core"
850
- version = "0.2.2"
892
+ version = "0.2.3"
851
893
  dependencies = [
852
894
  "chrono",
853
895
  "cron",
@@ -855,6 +897,7 @@ dependencies = [
855
897
  "diesel",
856
898
  "libsqlite3-sys",
857
899
  "log",
900
+ "pq-sys",
858
901
  "rand",
859
902
  "serde",
860
903
  "serde_json",
@@ -866,7 +909,7 @@ dependencies = [
866
909
 
867
910
  [[package]]
868
911
  name = "taskito-python"
869
- version = "0.2.2"
912
+ version = "0.2.3"
870
913
  dependencies = [
871
914
  "crossbeam-channel",
872
915
  "pyo3",
@@ -5,6 +5,7 @@ resolver = "2"
5
5
  [workspace.dependencies]
6
6
  diesel = { version = "2.2", features = ["sqlite", "r2d2", "returning_clauses_for_sqlite_3_35"] }
7
7
  libsqlite3-sys = { version = "0.30", features = ["bundled"] }
8
+ pq-sys = { version = "0.6", features = ["bundled"] }
8
9
  uuid = { version = "1", features = ["v7"] }
9
10
  tokio = { version = "1", features = ["full"] }
10
11
  serde = { version = "1", features = ["derive"] }
@@ -1,20 +1,23 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: taskito
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Requires-Dist: cloudpickle>=3.0
5
5
  Requires-Dist: pytest>=7.0 ; extra == 'dev'
6
6
  Requires-Dist: pytest-asyncio>=0.21 ; extra == 'dev'
7
7
  Requires-Dist: ruff>=0.8 ; extra == 'dev'
8
8
  Requires-Dist: mypy>=1.13 ; extra == 'dev'
9
+ Requires-Dist: django>=3.2 ; extra == 'django'
9
10
  Requires-Dist: zensical ; extra == 'docs'
10
11
  Requires-Dist: fastapi>=0.100.0 ; extra == 'fastapi'
11
12
  Requires-Dist: pydantic>=2.0 ; extra == 'fastapi'
12
13
  Requires-Dist: opentelemetry-api ; extra == 'otel'
13
14
  Requires-Dist: opentelemetry-sdk ; extra == 'otel'
14
15
  Provides-Extra: dev
16
+ Provides-Extra: django
15
17
  Provides-Extra: docs
16
18
  Provides-Extra: fastapi
17
19
  Provides-Extra: otel
20
+ Provides-Extra: postgres
18
21
  License-File: LICENSE
19
22
  Summary: Rust-powered task queue for Python. No broker required.
20
23
  Requires-Python: >=3.9
@@ -26,10 +29,11 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
26
29
  [![Python versions](https://img.shields.io/pypi/pyversions/taskito.svg)](https://pypi.org/project/taskito/)
27
30
  [![License](https://img.shields.io/pypi/l/taskito.svg)](https://github.com/pratyush618/taskito/blob/master/LICENSE)
28
31
 
29
- A Rust-powered task queue for Python. No broker required — just SQLite.
32
+ A Rust-powered task queue for Python. No broker required — just SQLite or Postgres.
30
33
 
31
34
  ```
32
- pip install taskito
35
+ pip install taskito # SQLite (default)
36
+ pip install taskito[postgres] # with Postgres backend
33
37
  ```
34
38
 
35
39
  ## Quickstart
@@ -63,7 +67,7 @@ print(job.result(timeout=10)) # 5
63
67
 
64
68
  ## Why taskito?
65
69
 
66
- Most Python task queues require a separate broker (Redis, RabbitMQ) even for single-machine workloads. taskito embeds everything — storage, scheduling, and worker management — into a single `pip install` with no external dependencies beyond Python itself.
70
+ Most Python task queues require a separate broker (Redis, RabbitMQ) even for single-machine workloads. taskito embeds everything — storage, scheduling, and worker management — into a single `pip install` with no external dependencies beyond Python itself. For distributed setups, an optional Postgres backend enables multi-machine workers with the same API.
67
71
 
68
72
  The heavy lifting runs in Rust: a Tokio async scheduler, OS thread worker pool with crossbeam channels, and Diesel ORM over SQLite in WAL mode. Python's GIL is only held during task execution.
69
73
 
@@ -93,6 +97,7 @@ The heavy lifting runs in Rust: a Tokio async scheduler, OS thread worker pool w
93
97
  - **Async support** — `await job.aresult()`, `await queue.astats()`
94
98
  - **Web dashboard** — `taskito dashboard --app myapp:queue` serves a built-in monitoring UI
95
99
  - **FastAPI integration** — `TaskitoRouter` for instant REST API over the queue
100
+ - **Postgres backend** — optional multi-machine storage via PostgreSQL
96
101
  - **CLI** — `taskito worker`, `taskito info --watch`, `taskito dashboard`
97
102
 
98
103
  ## Examples
@@ -149,7 +154,7 @@ chord([download.s(u) for u in urls], merge.s()).apply()
149
154
  ### Periodic Tasks
150
155
 
151
156
  ```python
152
- @queue.periodic(cron="0 */6 * * *")
157
+ @queue.periodic(cron="0 0 */6 * * *")
153
158
  def cleanup_temp_files():
154
159
  ...
155
160
  ```
@@ -278,6 +283,7 @@ Coming from Celery? See the **[Migration Guide](https://taskito-sepia.vercel.app
278
283
  | Per-task middleware | **Yes** | No | No | Yes | No |
279
284
  | Cancel running tasks | **Yes** | Yes | No | No | No |
280
285
  | Custom serializers | **Yes** | Yes | No | No | No |
286
+ | Postgres backend | **Yes** | Yes | No | No | No |
281
287
  | Setup | **`pip install`** | Broker + backend | Redis | Broker | Redis |
282
288
 
283
289
  ## License
@@ -4,10 +4,11 @@
4
4
  [![Python versions](https://img.shields.io/pypi/pyversions/taskito.svg)](https://pypi.org/project/taskito/)
5
5
  [![License](https://img.shields.io/pypi/l/taskito.svg)](https://github.com/pratyush618/taskito/blob/master/LICENSE)
6
6
 
7
- A Rust-powered task queue for Python. No broker required — just SQLite.
7
+ A Rust-powered task queue for Python. No broker required — just SQLite or Postgres.
8
8
 
9
9
  ```
10
- pip install taskito
10
+ pip install taskito # SQLite (default)
11
+ pip install taskito[postgres] # with Postgres backend
11
12
  ```
12
13
 
13
14
  ## Quickstart
@@ -41,7 +42,7 @@ print(job.result(timeout=10)) # 5
41
42
 
42
43
  ## Why taskito?
43
44
 
44
- Most Python task queues require a separate broker (Redis, RabbitMQ) even for single-machine workloads. taskito embeds everything — storage, scheduling, and worker management — into a single `pip install` with no external dependencies beyond Python itself.
45
+ Most Python task queues require a separate broker (Redis, RabbitMQ) even for single-machine workloads. taskito embeds everything — storage, scheduling, and worker management — into a single `pip install` with no external dependencies beyond Python itself. For distributed setups, an optional Postgres backend enables multi-machine workers with the same API.
45
46
 
46
47
  The heavy lifting runs in Rust: a Tokio async scheduler, OS thread worker pool with crossbeam channels, and Diesel ORM over SQLite in WAL mode. Python's GIL is only held during task execution.
47
48
 
@@ -71,6 +72,7 @@ The heavy lifting runs in Rust: a Tokio async scheduler, OS thread worker pool w
71
72
  - **Async support** — `await job.aresult()`, `await queue.astats()`
72
73
  - **Web dashboard** — `taskito dashboard --app myapp:queue` serves a built-in monitoring UI
73
74
  - **FastAPI integration** — `TaskitoRouter` for instant REST API over the queue
75
+ - **Postgres backend** — optional multi-machine storage via PostgreSQL
74
76
  - **CLI** — `taskito worker`, `taskito info --watch`, `taskito dashboard`
75
77
 
76
78
  ## Examples
@@ -127,7 +129,7 @@ chord([download.s(u) for u in urls], merge.s()).apply()
127
129
  ### Periodic Tasks
128
130
 
129
131
  ```python
130
- @queue.periodic(cron="0 */6 * * *")
132
+ @queue.periodic(cron="0 0 */6 * * *")
131
133
  def cleanup_temp_files():
132
134
  ...
133
135
  ```
@@ -256,6 +258,7 @@ Coming from Celery? See the **[Migration Guide](https://taskito-sepia.vercel.app
256
258
  | Per-task middleware | **Yes** | No | No | Yes | No |
257
259
  | Cancel running tasks | **Yes** | Yes | No | No | No |
258
260
  | Custom serializers | **Yes** | Yes | No | No | No |
261
+ | Postgres backend | **Yes** | Yes | No | No | No |
259
262
  | Setup | **`pip install`** | Broker + backend | Redis | Broker | Redis |
260
263
 
261
264
  ## License
@@ -1,11 +1,16 @@
1
1
  [package]
2
2
  name = "taskito-core"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  edition = "2021"
5
5
 
6
+ [features]
7
+ default = []
8
+ postgres = ["diesel/postgres", "pq-sys"]
9
+
6
10
  [dependencies]
7
11
  diesel = { workspace = true }
8
12
  libsqlite3-sys = { workspace = true }
13
+ pq-sys = { workspace = true, optional = true }
9
14
  uuid = { workspace = true }
10
15
  tokio = { workspace = true }
11
16
  serde = { workspace = true }
@@ -1,5 +1,5 @@
1
1
  use serde::{Deserialize, Serialize};
2
- use std::time::{SystemTime, UNIX_EPOCH};
2
+ use std::time::{Duration, SystemTime, UNIX_EPOCH};
3
3
  use uuid::Uuid;
4
4
 
5
5
  use crate::storage::models::JobRow;
@@ -142,6 +142,6 @@ impl NewJob {
142
142
  pub fn now_millis() -> i64 {
143
143
  SystemTime::now()
144
144
  .duration_since(UNIX_EPOCH)
145
- .expect("time went backwards")
145
+ .unwrap_or(Duration::ZERO)
146
146
  .as_millis() as i64
147
147
  }
@@ -1,13 +1,16 @@
1
- pub mod job;
2
1
  pub mod error;
3
- pub mod storage;
4
- pub mod scheduler;
2
+ pub mod job;
5
3
  pub mod periodic;
6
4
  pub mod resilience;
5
+ pub mod scheduler;
6
+ pub mod storage;
7
7
 
8
8
  // Primary public API — the types most consumers need.
9
9
  pub use error::QueueError;
10
10
  pub use job::{Job, JobStatus, NewJob};
11
11
  pub use scheduler::{Scheduler, SchedulerConfig};
12
+ #[cfg(feature = "postgres")]
13
+ pub use storage::postgres::PostgresStorage;
12
14
  pub use storage::sqlite::SqliteStorage;
13
15
  pub use storage::Storage;
16
+ pub use storage::StorageBackend;
@@ -8,12 +8,10 @@ use crate::error::{QueueError, Result};
8
8
  /// Compute the next run time (in UNIX milliseconds) for a cron expression,
9
9
  /// starting from `after_ms` (also UNIX milliseconds).
10
10
  pub fn next_cron_time(cron_expr: &str, after_ms: i64) -> Result<i64> {
11
- let schedule = Schedule::from_str(cron_expr).map_err(|e| {
12
- QueueError::Config(format!("invalid cron expression '{cron_expr}': {e}"))
13
- })?;
11
+ let schedule = Schedule::from_str(cron_expr)
12
+ .map_err(|e| QueueError::Config(format!("invalid cron expression '{cron_expr}': {e}")))?;
14
13
 
15
- let after_dt = chrono::DateTime::from_timestamp_millis(after_ms)
16
- .unwrap_or_else(Utc::now);
14
+ let after_dt = chrono::DateTime::from_timestamp_millis(after_ms).unwrap_or_else(Utc::now);
17
15
 
18
16
  let next = schedule
19
17
  .after(&after_dt)
@@ -1,7 +1,7 @@
1
1
  use crate::error::Result;
2
2
  use crate::job::now_millis;
3
3
  use crate::storage::models::CircuitBreakerRow;
4
- use crate::storage::sqlite::SqliteStorage;
4
+ use crate::storage::{Storage, StorageBackend};
5
5
 
6
6
  /// Circuit breaker states.
7
7
  #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -40,11 +40,11 @@ pub struct CircuitBreakerConfig {
40
40
 
41
41
  /// Circuit breaker manager backed by SQLite.
42
42
  pub struct CircuitBreaker {
43
- storage: SqliteStorage,
43
+ storage: StorageBackend,
44
44
  }
45
45
 
46
46
  impl CircuitBreaker {
47
- pub fn new(storage: SqliteStorage) -> Self {
47
+ pub fn new(storage: StorageBackend) -> Self {
48
48
  Self { storage }
49
49
  }
50
50
 
@@ -1,14 +1,14 @@
1
1
  use crate::error::Result;
2
2
  use crate::job::Job;
3
- use crate::storage::sqlite::{SqliteStorage, DeadJob};
3
+ use crate::storage::{DeadJob, Storage, StorageBackend};
4
4
 
5
5
  /// Dead letter queue manager.
6
6
  pub struct DeadLetterQueue {
7
- storage: SqliteStorage,
7
+ storage: StorageBackend,
8
8
  }
9
9
 
10
10
  impl DeadLetterQueue {
11
- pub fn new(storage: SqliteStorage) -> Self {
11
+ pub fn new(storage: StorageBackend) -> Self {
12
12
  Self { storage }
13
13
  }
14
14
 
@@ -1,9 +1,9 @@
1
1
  use crate::error::Result;
2
- use crate::storage::sqlite::SqliteStorage;
2
+ use crate::storage::{Storage, StorageBackend};
3
3
 
4
4
  /// Token bucket rate limiter backed by SQLite for persistence.
5
5
  pub struct RateLimiter {
6
- storage: SqliteStorage,
6
+ storage: StorageBackend,
7
7
  }
8
8
 
9
9
  /// Parsed rate limit configuration (e.g., "100/m" → 100 tokens, refill 1.667/s).
@@ -37,7 +37,7 @@ impl RateLimitConfig {
37
37
  }
38
38
 
39
39
  impl RateLimiter {
40
- pub fn new(storage: SqliteStorage) -> Self {
40
+ pub fn new(storage: StorageBackend) -> Self {
41
41
  Self { storage }
42
42
  }
43
43
 
@@ -71,7 +71,8 @@ mod tests {
71
71
 
72
72
  #[test]
73
73
  fn test_token_bucket() {
74
- let storage = SqliteStorage::in_memory().unwrap();
74
+ let storage =
75
+ StorageBackend::Sqlite(crate::storage::sqlite::SqliteStorage::in_memory().unwrap());
75
76
  let limiter = RateLimiter::new(storage);
76
77
  let config = RateLimitConfig {
77
78
  max_tokens: 3.0,
@@ -89,13 +90,15 @@ mod tests {
89
90
 
90
91
  #[test]
91
92
  fn test_concurrent_token_acquisition() {
92
- use std::sync::Arc;
93
93
  use std::sync::atomic::{AtomicUsize, Ordering};
94
+ use std::sync::Arc;
94
95
  use std::sync::Barrier;
95
96
 
96
97
  let dir = tempfile::tempdir().unwrap();
97
98
  let db_path = dir.path().join("rate_limit_test.db");
98
- let storage = SqliteStorage::new(db_path.to_str().unwrap()).unwrap();
99
+ let storage = StorageBackend::Sqlite(
100
+ crate::storage::sqlite::SqliteStorage::new(db_path.to_str().unwrap()).unwrap(),
101
+ );
99
102
  let limiter = Arc::new(RateLimiter::new(storage));
100
103
  let config = RateLimitConfig {
101
104
  max_tokens: 10.0,
@@ -15,8 +15,8 @@ impl Default for RetryPolicy {
15
15
  fn default() -> Self {
16
16
  Self {
17
17
  max_retries: 3,
18
- base_delay_ms: 1_000, // 1 second
19
- max_delay_ms: 300_000, // 5 minutes
18
+ base_delay_ms: 1_000, // 1 second
19
+ max_delay_ms: 300_000, // 5 minutes
20
20
  }
21
21
  }
22
22
  }