pgtask 0.1.3__tar.gz → 0.3.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.
- {pgtask-0.1.3 → pgtask-0.3.0}/Cargo.lock +143 -9
- {pgtask-0.1.3 → pgtask-0.3.0}/Cargo.toml +3 -1
- pgtask-0.3.0/PKG-INFO +107 -0
- pgtask-0.3.0/README.md +88 -0
- pgtask-0.3.0/crates/pgtask/Cargo.toml +23 -0
- pgtask-0.3.0/crates/pgtask/README.md +100 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask/src/lib.rs +1 -1
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/Cargo.toml +4 -0
- pgtask-0.3.0/crates/pgtask-core/README.md +13 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/src/lib.rs +1 -1
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/src/schedule.rs +15 -10
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/src/task.rs +1 -0
- pgtask-0.3.0/crates/pgtask-core/tests/.gitignore +4 -0
- pgtask-0.3.0/crates/pgtask-core/tests/retry_properties.rs +124 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/tests/schedule_clock.rs +10 -9
- pgtask-0.3.0/crates/pgtask-core/tests/schedule_properties.rs +231 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-otel/Cargo.toml +1 -0
- pgtask-0.3.0/crates/pgtask-otel/README.md +13 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-otel/src/lib.rs +3 -3
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-otel/src/metrics.rs +15 -4
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/Cargo.toml +7 -2
- pgtask-0.3.0/crates/pgtask-postgres/README.md +15 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0003_remove_redundant_notifications.sql +63 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0004_sample_queue_demand.sql +176 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0005_serialise_result_wait_registration.sql +164 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0006_keep_resumed_tasks_claimable.sql +91 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0007_backfill_failed_attempts.sql +11 -0
- pgtask-0.3.0/crates/pgtask-postgres/migrations/0008_index_worker_pagination.sql +1 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/src/lib.rs +2 -2
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/src/store.rs +63 -15
- pgtask-0.3.0/crates/pgtask-postgres/tests/.gitignore +4 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/corruption.rs +3 -1
- pgtask-0.3.0/crates/pgtask-postgres/tests/guarantees.rs +740 -0
- pgtask-0.3.0/crates/pgtask-postgres/tests/linearizability.rs +1340 -0
- pgtask-0.3.0/crates/pgtask-postgres/tests/model.rs +476 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/queue.rs +258 -8
- pgtask-0.3.0/crates/pgtask-postgres/tests/races.rs +364 -0
- pgtask-0.3.0/crates/pgtask-postgres/tests/result_wait_locking.rs +219 -0
- pgtask-0.3.0/crates/pgtask-postgres/tests/round_trip_properties.rs +184 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/schedule.rs +37 -13
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/sql_surface.rs +10 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/sql_surface.txt +3 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/Cargo.toml +4 -3
- pgtask-0.3.0/crates/pgtask-worker/README.md +13 -0
- pgtask-0.3.0/crates/pgtask-worker/src/lib.rs +17 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/src/runtime.rs +97 -37
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/tests/worker.rs +344 -9
- {pgtask-0.1.3 → pgtask-0.3.0}/python/pgtask/__init__.py +4 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/python/pgtask/_native.pyi +1 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/python/pgtask/client.py +57 -4
- {pgtask-0.1.3 → pgtask-0.3.0}/sdks/python/Cargo.toml +1 -1
- pgtask-0.3.0/sdks/python/README.md +88 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/sdks/python/src/lib.rs +13 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/sdks/python/tests/test_python_sdk.py +158 -1
- pgtask-0.1.3/PKG-INFO +0 -42
- pgtask-0.1.3/README.md +0 -23
- pgtask-0.1.3/crates/pgtask/Cargo.toml +0 -20
- pgtask-0.1.3/crates/pgtask-worker/src/lib.rs +0 -11
- pgtask-0.1.3/sdks/python/README.md +0 -23
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask/tests/public_api.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/src/identifier.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/src/retry.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-core/tests/types.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-otel/src/propagation.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-otel/tests/propagation.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/build.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/migrations/0001_initial.sql +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/results.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/signals.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-postgres/tests/sql_surface_baseline.txt +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/src/health.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/src/registry.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/crates/pgtask-worker/tests/durable_restarts.rs +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/pyproject.toml +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/python/pgtask/py.typed +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/sdks/python/tests/__init__.py +0 -0
- {pgtask-0.1.3 → pgtask-0.3.0}/sdks/python/uv.lock +0 -0
|
@@ -155,6 +155,21 @@ version = "0.22.1"
|
|
|
155
155
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
156
156
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
|
157
157
|
|
|
158
|
+
[[package]]
|
|
159
|
+
name = "bit-set"
|
|
160
|
+
version = "0.8.0"
|
|
161
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
162
|
+
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
|
|
163
|
+
dependencies = [
|
|
164
|
+
"bit-vec",
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
[[package]]
|
|
168
|
+
name = "bit-vec"
|
|
169
|
+
version = "0.8.0"
|
|
170
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
171
|
+
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
|
|
172
|
+
|
|
158
173
|
[[package]]
|
|
159
174
|
name = "bitflags"
|
|
160
175
|
version = "2.13.1"
|
|
@@ -480,6 +495,12 @@ dependencies = [
|
|
|
480
495
|
"pin-project-lite",
|
|
481
496
|
]
|
|
482
497
|
|
|
498
|
+
[[package]]
|
|
499
|
+
name = "fastrand"
|
|
500
|
+
version = "2.5.0"
|
|
501
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
502
|
+
checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
|
|
503
|
+
|
|
483
504
|
[[package]]
|
|
484
505
|
name = "find-msvc-tools"
|
|
485
506
|
version = "0.1.11"
|
|
@@ -497,6 +518,12 @@ dependencies = [
|
|
|
497
518
|
"spin",
|
|
498
519
|
]
|
|
499
520
|
|
|
521
|
+
[[package]]
|
|
522
|
+
name = "fnv"
|
|
523
|
+
version = "1.0.7"
|
|
524
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
525
|
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|
526
|
+
|
|
500
527
|
[[package]]
|
|
501
528
|
name = "foldhash"
|
|
502
529
|
version = "0.2.0"
|
|
@@ -990,6 +1017,12 @@ dependencies = [
|
|
|
990
1017
|
"vcpkg",
|
|
991
1018
|
]
|
|
992
1019
|
|
|
1020
|
+
[[package]]
|
|
1021
|
+
name = "linux-raw-sys"
|
|
1022
|
+
version = "0.12.1"
|
|
1023
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1024
|
+
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
|
1025
|
+
|
|
993
1026
|
[[package]]
|
|
994
1027
|
name = "litemap"
|
|
995
1028
|
version = "0.8.3"
|
|
@@ -1162,18 +1195,20 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
|
|
1162
1195
|
|
|
1163
1196
|
[[package]]
|
|
1164
1197
|
name = "pgtask"
|
|
1165
|
-
version = "0.
|
|
1198
|
+
version = "0.3.0"
|
|
1166
1199
|
dependencies = [
|
|
1167
1200
|
"pgtask-core",
|
|
1168
1201
|
"pgtask-otel",
|
|
1169
1202
|
"pgtask-postgres",
|
|
1170
1203
|
"pgtask-worker",
|
|
1171
1204
|
"serde_json",
|
|
1205
|
+
"tokio",
|
|
1206
|
+
"tokio-util",
|
|
1172
1207
|
]
|
|
1173
1208
|
|
|
1174
1209
|
[[package]]
|
|
1175
1210
|
name = "pgtask-bench"
|
|
1176
|
-
version = "0.
|
|
1211
|
+
version = "0.3.0"
|
|
1177
1212
|
dependencies = [
|
|
1178
1213
|
"chrono",
|
|
1179
1214
|
"pgtask",
|
|
@@ -1186,7 +1221,7 @@ dependencies = [
|
|
|
1186
1221
|
|
|
1187
1222
|
[[package]]
|
|
1188
1223
|
name = "pgtask-cli"
|
|
1189
|
-
version = "0.
|
|
1224
|
+
version = "0.3.0"
|
|
1190
1225
|
dependencies = [
|
|
1191
1226
|
"clap",
|
|
1192
1227
|
"pgtask",
|
|
@@ -1196,10 +1231,11 @@ dependencies = [
|
|
|
1196
1231
|
|
|
1197
1232
|
[[package]]
|
|
1198
1233
|
name = "pgtask-core"
|
|
1199
|
-
version = "0.
|
|
1234
|
+
version = "0.3.0"
|
|
1200
1235
|
dependencies = [
|
|
1201
1236
|
"chrono",
|
|
1202
1237
|
"cron",
|
|
1238
|
+
"proptest",
|
|
1203
1239
|
"rand 0.9.5",
|
|
1204
1240
|
"serde",
|
|
1205
1241
|
"serde_json",
|
|
@@ -1209,7 +1245,7 @@ dependencies = [
|
|
|
1209
1245
|
|
|
1210
1246
|
[[package]]
|
|
1211
1247
|
name = "pgtask-otel"
|
|
1212
|
-
version = "0.
|
|
1248
|
+
version = "0.3.0"
|
|
1213
1249
|
dependencies = [
|
|
1214
1250
|
"opentelemetry",
|
|
1215
1251
|
"opentelemetry_sdk",
|
|
@@ -1220,11 +1256,13 @@ dependencies = [
|
|
|
1220
1256
|
|
|
1221
1257
|
[[package]]
|
|
1222
1258
|
name = "pgtask-postgres"
|
|
1223
|
-
version = "0.
|
|
1259
|
+
version = "0.3.0"
|
|
1224
1260
|
dependencies = [
|
|
1225
1261
|
"chrono",
|
|
1226
1262
|
"pgtask-core",
|
|
1227
1263
|
"pgtask-otel",
|
|
1264
|
+
"proptest",
|
|
1265
|
+
"proptest-state-machine",
|
|
1228
1266
|
"serde_json",
|
|
1229
1267
|
"sqlx",
|
|
1230
1268
|
"thiserror",
|
|
@@ -1235,7 +1273,7 @@ dependencies = [
|
|
|
1235
1273
|
|
|
1236
1274
|
[[package]]
|
|
1237
1275
|
name = "pgtask-python"
|
|
1238
|
-
version = "0.
|
|
1276
|
+
version = "0.3.0"
|
|
1239
1277
|
dependencies = [
|
|
1240
1278
|
"chrono",
|
|
1241
1279
|
"pgtask",
|
|
@@ -1252,7 +1290,7 @@ dependencies = [
|
|
|
1252
1290
|
|
|
1253
1291
|
[[package]]
|
|
1254
1292
|
name = "pgtask-web"
|
|
1255
|
-
version = "0.
|
|
1293
|
+
version = "0.3.0"
|
|
1256
1294
|
dependencies = [
|
|
1257
1295
|
"axum",
|
|
1258
1296
|
"chrono",
|
|
@@ -1271,7 +1309,7 @@ dependencies = [
|
|
|
1271
1309
|
|
|
1272
1310
|
[[package]]
|
|
1273
1311
|
name = "pgtask-worker"
|
|
1274
|
-
version = "0.
|
|
1312
|
+
version = "0.3.0"
|
|
1275
1313
|
dependencies = [
|
|
1276
1314
|
"axum",
|
|
1277
1315
|
"chrono",
|
|
@@ -1375,6 +1413,34 @@ dependencies = [
|
|
|
1375
1413
|
"unicode-ident",
|
|
1376
1414
|
]
|
|
1377
1415
|
|
|
1416
|
+
[[package]]
|
|
1417
|
+
name = "proptest"
|
|
1418
|
+
version = "1.11.0"
|
|
1419
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1420
|
+
checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
|
|
1421
|
+
dependencies = [
|
|
1422
|
+
"bit-set",
|
|
1423
|
+
"bit-vec",
|
|
1424
|
+
"bitflags",
|
|
1425
|
+
"num-traits",
|
|
1426
|
+
"rand 0.9.5",
|
|
1427
|
+
"rand_chacha",
|
|
1428
|
+
"rand_xorshift",
|
|
1429
|
+
"regex-syntax",
|
|
1430
|
+
"rusty-fork",
|
|
1431
|
+
"tempfile",
|
|
1432
|
+
"unarray",
|
|
1433
|
+
]
|
|
1434
|
+
|
|
1435
|
+
[[package]]
|
|
1436
|
+
name = "proptest-state-machine"
|
|
1437
|
+
version = "0.3.1"
|
|
1438
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1439
|
+
checksum = "e943d140e09d07740fb496487c51fb8eb31c70389ac4a2e9dcd8a0d9fdf228d4"
|
|
1440
|
+
dependencies = [
|
|
1441
|
+
"proptest",
|
|
1442
|
+
]
|
|
1443
|
+
|
|
1378
1444
|
[[package]]
|
|
1379
1445
|
name = "pyo3"
|
|
1380
1446
|
version = "0.29.2"
|
|
@@ -1456,6 +1522,12 @@ dependencies = [
|
|
|
1456
1522
|
"serde",
|
|
1457
1523
|
]
|
|
1458
1524
|
|
|
1525
|
+
[[package]]
|
|
1526
|
+
name = "quick-error"
|
|
1527
|
+
version = "1.2.3"
|
|
1528
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1529
|
+
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
|
1530
|
+
|
|
1459
1531
|
[[package]]
|
|
1460
1532
|
name = "quote"
|
|
1461
1533
|
version = "1.0.47"
|
|
@@ -1538,6 +1610,15 @@ version = "0.10.1"
|
|
|
1538
1610
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1539
1611
|
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
|
1540
1612
|
|
|
1613
|
+
[[package]]
|
|
1614
|
+
name = "rand_xorshift"
|
|
1615
|
+
version = "0.4.0"
|
|
1616
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1617
|
+
checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
|
|
1618
|
+
dependencies = [
|
|
1619
|
+
"rand_core 0.9.5",
|
|
1620
|
+
]
|
|
1621
|
+
|
|
1541
1622
|
[[package]]
|
|
1542
1623
|
name = "redox_syscall"
|
|
1543
1624
|
version = "0.5.18"
|
|
@@ -1578,6 +1659,19 @@ dependencies = [
|
|
|
1578
1659
|
"windows-sys 0.52.0",
|
|
1579
1660
|
]
|
|
1580
1661
|
|
|
1662
|
+
[[package]]
|
|
1663
|
+
name = "rustix"
|
|
1664
|
+
version = "1.1.4"
|
|
1665
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1666
|
+
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
|
1667
|
+
dependencies = [
|
|
1668
|
+
"bitflags",
|
|
1669
|
+
"errno",
|
|
1670
|
+
"libc",
|
|
1671
|
+
"linux-raw-sys",
|
|
1672
|
+
"windows-sys 0.61.2",
|
|
1673
|
+
]
|
|
1674
|
+
|
|
1581
1675
|
[[package]]
|
|
1582
1676
|
name = "rustls"
|
|
1583
1677
|
version = "0.23.43"
|
|
@@ -1630,6 +1724,18 @@ version = "1.0.23"
|
|
|
1630
1724
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1631
1725
|
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
1632
1726
|
|
|
1727
|
+
[[package]]
|
|
1728
|
+
name = "rusty-fork"
|
|
1729
|
+
version = "0.3.1"
|
|
1730
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1731
|
+
checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2"
|
|
1732
|
+
dependencies = [
|
|
1733
|
+
"fnv",
|
|
1734
|
+
"quick-error",
|
|
1735
|
+
"tempfile",
|
|
1736
|
+
"wait-timeout",
|
|
1737
|
+
]
|
|
1738
|
+
|
|
1633
1739
|
[[package]]
|
|
1634
1740
|
name = "ryu"
|
|
1635
1741
|
version = "1.0.23"
|
|
@@ -2093,6 +2199,19 @@ version = "0.13.5"
|
|
|
2093
2199
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2094
2200
|
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
2095
2201
|
|
|
2202
|
+
[[package]]
|
|
2203
|
+
name = "tempfile"
|
|
2204
|
+
version = "3.27.0"
|
|
2205
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2206
|
+
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
|
2207
|
+
dependencies = [
|
|
2208
|
+
"fastrand",
|
|
2209
|
+
"getrandom 0.4.3",
|
|
2210
|
+
"once_cell",
|
|
2211
|
+
"rustix",
|
|
2212
|
+
"windows-sys 0.61.2",
|
|
2213
|
+
]
|
|
2214
|
+
|
|
2096
2215
|
[[package]]
|
|
2097
2216
|
name = "thiserror"
|
|
2098
2217
|
version = "2.0.20"
|
|
@@ -2310,6 +2429,12 @@ version = "1.20.1"
|
|
|
2310
2429
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2311
2430
|
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
|
|
2312
2431
|
|
|
2432
|
+
[[package]]
|
|
2433
|
+
name = "unarray"
|
|
2434
|
+
version = "0.1.4"
|
|
2435
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2436
|
+
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
|
2437
|
+
|
|
2313
2438
|
[[package]]
|
|
2314
2439
|
name = "unicode-bidi"
|
|
2315
2440
|
version = "0.3.18"
|
|
@@ -2397,6 +2522,15 @@ version = "0.9.5"
|
|
|
2397
2522
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2398
2523
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
2399
2524
|
|
|
2525
|
+
[[package]]
|
|
2526
|
+
name = "wait-timeout"
|
|
2527
|
+
version = "0.2.1"
|
|
2528
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2529
|
+
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
|
|
2530
|
+
dependencies = [
|
|
2531
|
+
"libc",
|
|
2532
|
+
]
|
|
2533
|
+
|
|
2400
2534
|
[[package]]
|
|
2401
2535
|
name = "wasi"
|
|
2402
2536
|
version = "0.11.1+wasi-snapshot-preview1"
|
|
@@ -7,7 +7,7 @@ edition = "2024"
|
|
|
7
7
|
license = "MIT"
|
|
8
8
|
repository = "https://github.com/Kludex/pgtask"
|
|
9
9
|
rust-version = "1.94"
|
|
10
|
-
version = "0.
|
|
10
|
+
version = "0.3.0"
|
|
11
11
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
13
|
axum = "0.8.9"
|
|
@@ -18,6 +18,8 @@ futures = "0.3.34"
|
|
|
18
18
|
html-escape = "0.2.15"
|
|
19
19
|
opentelemetry = "0.32.0"
|
|
20
20
|
opentelemetry_sdk = "0.32.1"
|
|
21
|
+
proptest = "1"
|
|
22
|
+
proptest-state-machine = "0.3"
|
|
21
23
|
pyo3 = "0.29.2"
|
|
22
24
|
pyo3-async-runtimes = "0.29.0"
|
|
23
25
|
pythonize = "0.29.0"
|
pgtask-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pgtask
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
5
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
|
+
Classifier: Programming Language :: Rust
|
|
12
|
+
Requires-Dist: opentelemetry-api>=1.30
|
|
13
|
+
Requires-Dist: psycopg>=3.2
|
|
14
|
+
Summary: PostgreSQL-native durable tasks and workflows
|
|
15
|
+
License-Expression: MIT
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
18
|
+
|
|
19
|
+
# pgtask
|
|
20
|
+
|
|
21
|
+
Durable tasks and workflows that live entirely in PostgreSQL.
|
|
22
|
+
|
|
23
|
+
There is no broker, no coordinator, and no extension to install. If your database is up, your queue is up.
|
|
24
|
+
|
|
25
|
+
> [!WARNING]
|
|
26
|
+
> `pgtask` is under active development. It is not ready for production use.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
```console
|
|
31
|
+
pip install pgtask
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Define a task and run a worker
|
|
35
|
+
|
|
36
|
+
A registry maps a task name to the function that runs it. A worker claims work for that queue, one lease
|
|
37
|
+
at a time, so a worker that dies hands its tasks back instead of taking them with it.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from __future__ import annotations
|
|
41
|
+
|
|
42
|
+
import asyncio
|
|
43
|
+
import os
|
|
44
|
+
|
|
45
|
+
from pgtask import Client, Task, TaskRegistry, Worker
|
|
46
|
+
|
|
47
|
+
tasks = TaskRegistry(queue_name="reports")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@tasks.task("reports.render")
|
|
51
|
+
async def render(task: Task, payload: dict) -> dict:
|
|
52
|
+
return {"report_id": payload["report_id"], "attempt": task.attempt}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
async def main() -> None:
|
|
56
|
+
database_url = os.environ["PGTASK_DATABASE_URL"]
|
|
57
|
+
client = await Client.connect(database_url)
|
|
58
|
+
await client.migrate()
|
|
59
|
+
await Worker(database_url, tasks).run()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
asyncio.run(main())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Delivery is at least once, so write handlers that are safe to run again.
|
|
66
|
+
|
|
67
|
+
## Enqueue a task
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from __future__ import annotations
|
|
71
|
+
|
|
72
|
+
import asyncio
|
|
73
|
+
import os
|
|
74
|
+
|
|
75
|
+
from pgtask import Client, EnqueueRequest
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
async def main() -> None:
|
|
79
|
+
client = await Client.connect(os.environ["PGTASK_DATABASE_URL"])
|
|
80
|
+
handle = await client.enqueue(
|
|
81
|
+
EnqueueRequest("reports.render", {"report_id": "report-123"}, queue_name="reports")
|
|
82
|
+
)
|
|
83
|
+
print(await handle.result(timeout=30.0))
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
asyncio.run(main())
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Enqueue inside your transaction
|
|
90
|
+
|
|
91
|
+
This is the reason to keep the queue in the database. Pass your own connection and the task commits with
|
|
92
|
+
your data or not at all. Roll back and the task never existed, which is what an outbox table is usually
|
|
93
|
+
for.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
async with connection.transaction():
|
|
97
|
+
await connection.execute("INSERT INTO reports (id) VALUES (%s)", ("report-123",))
|
|
98
|
+
await Client.enqueue_on(connection, request)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`connection` is your `psycopg` connection, not one of ours.
|
|
102
|
+
|
|
103
|
+
## Documentation
|
|
104
|
+
|
|
105
|
+
[kludex.github.io/pgtask](https://kludex.github.io/pgtask/) covers workers, durable execution, signals,
|
|
106
|
+
cancellation, scheduling, and OpenTelemetry propagation.
|
|
107
|
+
|
pgtask-0.3.0/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# pgtask
|
|
2
|
+
|
|
3
|
+
Durable tasks and workflows that live entirely in PostgreSQL.
|
|
4
|
+
|
|
5
|
+
There is no broker, no coordinator, and no extension to install. If your database is up, your queue is up.
|
|
6
|
+
|
|
7
|
+
> [!WARNING]
|
|
8
|
+
> `pgtask` is under active development. It is not ready for production use.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```console
|
|
13
|
+
pip install pgtask
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Define a task and run a worker
|
|
17
|
+
|
|
18
|
+
A registry maps a task name to the function that runs it. A worker claims work for that queue, one lease
|
|
19
|
+
at a time, so a worker that dies hands its tasks back instead of taking them with it.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import asyncio
|
|
25
|
+
import os
|
|
26
|
+
|
|
27
|
+
from pgtask import Client, Task, TaskRegistry, Worker
|
|
28
|
+
|
|
29
|
+
tasks = TaskRegistry(queue_name="reports")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@tasks.task("reports.render")
|
|
33
|
+
async def render(task: Task, payload: dict) -> dict:
|
|
34
|
+
return {"report_id": payload["report_id"], "attempt": task.attempt}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
async def main() -> None:
|
|
38
|
+
database_url = os.environ["PGTASK_DATABASE_URL"]
|
|
39
|
+
client = await Client.connect(database_url)
|
|
40
|
+
await client.migrate()
|
|
41
|
+
await Worker(database_url, tasks).run()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
asyncio.run(main())
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Delivery is at least once, so write handlers that are safe to run again.
|
|
48
|
+
|
|
49
|
+
## Enqueue a task
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from __future__ import annotations
|
|
53
|
+
|
|
54
|
+
import asyncio
|
|
55
|
+
import os
|
|
56
|
+
|
|
57
|
+
from pgtask import Client, EnqueueRequest
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async def main() -> None:
|
|
61
|
+
client = await Client.connect(os.environ["PGTASK_DATABASE_URL"])
|
|
62
|
+
handle = await client.enqueue(
|
|
63
|
+
EnqueueRequest("reports.render", {"report_id": "report-123"}, queue_name="reports")
|
|
64
|
+
)
|
|
65
|
+
print(await handle.result(timeout=30.0))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Enqueue inside your transaction
|
|
72
|
+
|
|
73
|
+
This is the reason to keep the queue in the database. Pass your own connection and the task commits with
|
|
74
|
+
your data or not at all. Roll back and the task never existed, which is what an outbox table is usually
|
|
75
|
+
for.
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
async with connection.transaction():
|
|
79
|
+
await connection.execute("INSERT INTO reports (id) VALUES (%s)", ("report-123",))
|
|
80
|
+
await Client.enqueue_on(connection, request)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`connection` is your `psycopg` connection, not one of ours.
|
|
84
|
+
|
|
85
|
+
## Documentation
|
|
86
|
+
|
|
87
|
+
[kludex.github.io/pgtask](https://kludex.github.io/pgtask/) covers workers, durable execution, signals,
|
|
88
|
+
cancellation, scheduling, and OpenTelemetry propagation.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "pgtask"
|
|
3
|
+
description = "PostgreSQL-native durable tasks and workflows"
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
license.workspace = true
|
|
6
|
+
repository.workspace = true
|
|
7
|
+
rust-version.workspace = true
|
|
8
|
+
version.workspace = true
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
pgtask-core = { path = "../pgtask-core", version = "0.3.0" }
|
|
13
|
+
pgtask-otel = { path = "../pgtask-otel", version = "0.3.0" }
|
|
14
|
+
pgtask-postgres = { path = "../pgtask-postgres", version = "0.3.0" }
|
|
15
|
+
pgtask-worker = { path = "../pgtask-worker", version = "0.3.0" }
|
|
16
|
+
|
|
17
|
+
[dev-dependencies]
|
|
18
|
+
serde_json.workspace = true
|
|
19
|
+
tokio.workspace = true
|
|
20
|
+
tokio-util.workspace = true
|
|
21
|
+
|
|
22
|
+
[lints]
|
|
23
|
+
workspace = true
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# pgtask
|
|
2
|
+
|
|
3
|
+
Durable tasks and workflows that live entirely in PostgreSQL.
|
|
4
|
+
|
|
5
|
+
There is no broker, no coordinator, and no extension to install. If your database is up, your queue is up.
|
|
6
|
+
|
|
7
|
+
> [!WARNING]
|
|
8
|
+
> `pgtask` is under active development. It is not ready for production use.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```console
|
|
13
|
+
cargo add pgtask tokio tokio-util serde_json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Run a worker
|
|
17
|
+
|
|
18
|
+
A worker declares which tasks it can handle and claims work from a queue. Every claim takes a lease, so
|
|
19
|
+
when a worker dies its tasks return to the queue instead of disappearing with it.
|
|
20
|
+
|
|
21
|
+
```rust,no_run
|
|
22
|
+
use std::error::Error;
|
|
23
|
+
|
|
24
|
+
use pgtask::{
|
|
25
|
+
core::{HandlerVersion, QueueName, RetryPolicy, TaskName},
|
|
26
|
+
postgres::Store,
|
|
27
|
+
worker::{HandlerRegistry, Worker, WorkerConfig},
|
|
28
|
+
};
|
|
29
|
+
use serde_json::json;
|
|
30
|
+
use tokio_util::sync::CancellationToken;
|
|
31
|
+
|
|
32
|
+
#[tokio::main]
|
|
33
|
+
async fn main() -> Result<(), Box<dyn Error>> {
|
|
34
|
+
let store = Store::connect(&std::env::var("PGTASK_DATABASE_URL")?).await?;
|
|
35
|
+
store.migrate().await?;
|
|
36
|
+
|
|
37
|
+
let mut registry = HandlerRegistry::new();
|
|
38
|
+
registry.register(
|
|
39
|
+
TaskName::new("reports.render")?,
|
|
40
|
+
HandlerVersion::default(),
|
|
41
|
+
RetryPolicy::Never,
|
|
42
|
+
|task| async move { Ok(json!({ "attempt": task.attempt })) },
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
let config = WorkerConfig::new(QueueName::new("reports")?);
|
|
46
|
+
Worker::new(store, registry, config)?.run(CancellationToken::new()).await?;
|
|
47
|
+
Ok(())
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Cancel the token to shut down. The worker stops claiming, finishes what it is already running, and lets
|
|
52
|
+
the rest expire back to the queue.
|
|
53
|
+
|
|
54
|
+
## Enqueue inside your transaction
|
|
55
|
+
|
|
56
|
+
This is the reason to keep the queue in the database. You pass your own transaction, so the task commits
|
|
57
|
+
with your data or not at all. Roll back and the task never existed.
|
|
58
|
+
|
|
59
|
+
```rust,no_run
|
|
60
|
+
use std::error::Error;
|
|
61
|
+
|
|
62
|
+
use pgtask::{
|
|
63
|
+
core::{EnqueueRequest, QueueName, TaskName},
|
|
64
|
+
postgres::Store,
|
|
65
|
+
};
|
|
66
|
+
use serde_json::json;
|
|
67
|
+
|
|
68
|
+
#[tokio::main]
|
|
69
|
+
async fn main() -> Result<(), Box<dyn Error>> {
|
|
70
|
+
let store = Store::connect(&std::env::var("PGTASK_DATABASE_URL")?).await?;
|
|
71
|
+
|
|
72
|
+
let mut request = EnqueueRequest::new(TaskName::new("reports.render")?, json!({"report_id": "report-123"}));
|
|
73
|
+
request.queue_name = QueueName::new("reports")?;
|
|
74
|
+
|
|
75
|
+
let mut transaction = store.pool().begin().await?;
|
|
76
|
+
// Your own writes belong here, in the same transaction.
|
|
77
|
+
let result = Store::enqueue_on(&mut transaction, &request).await?;
|
|
78
|
+
transaction.commit().await?;
|
|
79
|
+
|
|
80
|
+
println!("enqueued {}", result.task_id);
|
|
81
|
+
Ok(())
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Without a transaction of your own, `store.enqueue(&request)` does the same on its own connection.
|
|
86
|
+
|
|
87
|
+
## Crates
|
|
88
|
+
|
|
89
|
+
This crate re-exports the others. Depend on it unless you need one layer on its own.
|
|
90
|
+
|
|
91
|
+
| Crate | What it holds |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| `pgtask-core` | Task, queue, schedule, and retry types shared by every layer |
|
|
94
|
+
| `pgtask-postgres` | The storage protocol: migrate, enqueue, claim, complete |
|
|
95
|
+
| `pgtask-worker` | The worker runtime, scheduler, and retention loop |
|
|
96
|
+
| `pgtask-otel` | OpenTelemetry spans, metrics, and trace propagation |
|
|
97
|
+
|
|
98
|
+
## Documentation
|
|
99
|
+
|
|
100
|
+
[kludex.github.io/pgtask](https://kludex.github.io/pgtask/)
|
|
@@ -6,6 +6,7 @@ license.workspace = true
|
|
|
6
6
|
repository.workspace = true
|
|
7
7
|
rust-version.workspace = true
|
|
8
8
|
version.workspace = true
|
|
9
|
+
readme = "README.md"
|
|
9
10
|
|
|
10
11
|
[dependencies]
|
|
11
12
|
chrono.workspace = true
|
|
@@ -16,5 +17,8 @@ serde_json.workspace = true
|
|
|
16
17
|
thiserror.workspace = true
|
|
17
18
|
uuid.workspace = true
|
|
18
19
|
|
|
20
|
+
[dev-dependencies]
|
|
21
|
+
proptest.workspace = true
|
|
22
|
+
|
|
19
23
|
[lints]
|
|
20
24
|
workspace = true
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# pgtask-core
|
|
2
|
+
|
|
3
|
+
The types every layer of `pgtask` agrees on: tasks, queues, schedules, retry policies, and the states a
|
|
4
|
+
task can be in.
|
|
5
|
+
|
|
6
|
+
There is no database access and no runtime here. The crate exists so the storage layer, the worker, and
|
|
7
|
+
the telemetry layer share one definition of a task instead of three that drift apart.
|
|
8
|
+
|
|
9
|
+
You probably want [`pgtask`](https://crates.io/crates/pgtask), which re-exports this as `pgtask::core`.
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
[kludex.github.io/pgtask](https://kludex.github.io/pgtask/)
|
|
@@ -20,7 +20,7 @@ pub use task::{
|
|
|
20
20
|
pub const STORAGE_PROTOCOL_MIN_VERSION: u32 = 1;
|
|
21
21
|
|
|
22
22
|
/// Newest storage protocol understood by this release.
|
|
23
|
-
pub const STORAGE_PROTOCOL_MAX_VERSION: u32 =
|
|
23
|
+
pub const STORAGE_PROTOCOL_MAX_VERSION: u32 = 2;
|
|
24
24
|
|
|
25
25
|
/// Current storage protocol emitted by this release.
|
|
26
26
|
pub const STORAGE_PROTOCOL_VERSION: u32 = STORAGE_PROTOCOL_MAX_VERSION;
|