dbos 0.27.1__tar.gz → 0.27.2__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 (105) hide show
  1. {dbos-0.27.1 → dbos-0.27.2}/PKG-INFO +1 -1
  2. {dbos-0.27.1 → dbos-0.27.2}/dbos/_sys_db.py +16 -10
  3. {dbos-0.27.1 → dbos-0.27.2}/pyproject.toml +1 -1
  4. {dbos-0.27.1 → dbos-0.27.2}/tests/test_queue.py +27 -0
  5. {dbos-0.27.1 → dbos-0.27.2}/LICENSE +0 -0
  6. {dbos-0.27.1 → dbos-0.27.2}/README.md +0 -0
  7. {dbos-0.27.1 → dbos-0.27.2}/dbos/__init__.py +0 -0
  8. {dbos-0.27.1 → dbos-0.27.2}/dbos/__main__.py +0 -0
  9. {dbos-0.27.1 → dbos-0.27.2}/dbos/_admin_server.py +0 -0
  10. {dbos-0.27.1 → dbos-0.27.2}/dbos/_app_db.py +0 -0
  11. {dbos-0.27.1 → dbos-0.27.2}/dbos/_classproperty.py +0 -0
  12. {dbos-0.27.1 → dbos-0.27.2}/dbos/_client.py +0 -0
  13. {dbos-0.27.1 → dbos-0.27.2}/dbos/_conductor/conductor.py +0 -0
  14. {dbos-0.27.1 → dbos-0.27.2}/dbos/_conductor/protocol.py +0 -0
  15. {dbos-0.27.1 → dbos-0.27.2}/dbos/_context.py +0 -0
  16. {dbos-0.27.1 → dbos-0.27.2}/dbos/_core.py +0 -0
  17. {dbos-0.27.1 → dbos-0.27.2}/dbos/_croniter.py +0 -0
  18. {dbos-0.27.1 → dbos-0.27.2}/dbos/_dbos.py +0 -0
  19. {dbos-0.27.1 → dbos-0.27.2}/dbos/_dbos_config.py +0 -0
  20. {dbos-0.27.1 → dbos-0.27.2}/dbos/_debug.py +0 -0
  21. {dbos-0.27.1 → dbos-0.27.2}/dbos/_docker_pg_helper.py +0 -0
  22. {dbos-0.27.1 → dbos-0.27.2}/dbos/_error.py +0 -0
  23. {dbos-0.27.1 → dbos-0.27.2}/dbos/_event_loop.py +0 -0
  24. {dbos-0.27.1 → dbos-0.27.2}/dbos/_fastapi.py +0 -0
  25. {dbos-0.27.1 → dbos-0.27.2}/dbos/_flask.py +0 -0
  26. {dbos-0.27.1 → dbos-0.27.2}/dbos/_kafka.py +0 -0
  27. {dbos-0.27.1 → dbos-0.27.2}/dbos/_kafka_message.py +0 -0
  28. {dbos-0.27.1 → dbos-0.27.2}/dbos/_logger.py +0 -0
  29. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/env.py +0 -0
  30. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/script.py.mako +0 -0
  31. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
  32. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/27ac6900c6ad_add_queue_dedup.py +0 -0
  33. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
  34. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
  35. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/83f3732ae8e7_workflow_timeout.py +0 -0
  36. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
  37. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
  38. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
  39. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
  40. {dbos-0.27.1 → dbos-0.27.2}/dbos/_migrations/versions/f4b9b32ba814_functionname_childid_op_outputs.py +0 -0
  41. {dbos-0.27.1 → dbos-0.27.2}/dbos/_outcome.py +0 -0
  42. {dbos-0.27.1 → dbos-0.27.2}/dbos/_queue.py +0 -0
  43. {dbos-0.27.1 → dbos-0.27.2}/dbos/_recovery.py +0 -0
  44. {dbos-0.27.1 → dbos-0.27.2}/dbos/_registrations.py +0 -0
  45. {dbos-0.27.1 → dbos-0.27.2}/dbos/_request.py +0 -0
  46. {dbos-0.27.1 → dbos-0.27.2}/dbos/_roles.py +0 -0
  47. {dbos-0.27.1 → dbos-0.27.2}/dbos/_scheduler.py +0 -0
  48. {dbos-0.27.1 → dbos-0.27.2}/dbos/_schemas/__init__.py +0 -0
  49. {dbos-0.27.1 → dbos-0.27.2}/dbos/_schemas/application_database.py +0 -0
  50. {dbos-0.27.1 → dbos-0.27.2}/dbos/_schemas/system_database.py +0 -0
  51. {dbos-0.27.1 → dbos-0.27.2}/dbos/_serialization.py +0 -0
  52. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/README.md +0 -0
  53. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  54. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
  55. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  56. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
  57. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
  58. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
  59. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
  60. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
  61. {dbos-0.27.1 → dbos-0.27.2}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  62. {dbos-0.27.1 → dbos-0.27.2}/dbos/_tracer.py +0 -0
  63. {dbos-0.27.1 → dbos-0.27.2}/dbos/_utils.py +0 -0
  64. {dbos-0.27.1 → dbos-0.27.2}/dbos/_workflow_commands.py +0 -0
  65. {dbos-0.27.1 → dbos-0.27.2}/dbos/cli/_github_init.py +0 -0
  66. {dbos-0.27.1 → dbos-0.27.2}/dbos/cli/_template_init.py +0 -0
  67. {dbos-0.27.1 → dbos-0.27.2}/dbos/cli/cli.py +0 -0
  68. {dbos-0.27.1 → dbos-0.27.2}/dbos/dbos-config.schema.json +0 -0
  69. {dbos-0.27.1 → dbos-0.27.2}/dbos/py.typed +0 -0
  70. {dbos-0.27.1 → dbos-0.27.2}/tests/__init__.py +0 -0
  71. {dbos-0.27.1 → dbos-0.27.2}/tests/atexit_no_ctor.py +0 -0
  72. {dbos-0.27.1 → dbos-0.27.2}/tests/atexit_no_launch.py +0 -0
  73. {dbos-0.27.1 → dbos-0.27.2}/tests/classdefs.py +0 -0
  74. {dbos-0.27.1 → dbos-0.27.2}/tests/client_collateral.py +0 -0
  75. {dbos-0.27.1 → dbos-0.27.2}/tests/client_worker.py +0 -0
  76. {dbos-0.27.1 → dbos-0.27.2}/tests/conftest.py +0 -0
  77. {dbos-0.27.1 → dbos-0.27.2}/tests/dupname_classdefs1.py +0 -0
  78. {dbos-0.27.1 → dbos-0.27.2}/tests/dupname_classdefsa.py +0 -0
  79. {dbos-0.27.1 → dbos-0.27.2}/tests/more_classdefs.py +0 -0
  80. {dbos-0.27.1 → dbos-0.27.2}/tests/queuedworkflow.py +0 -0
  81. {dbos-0.27.1 → dbos-0.27.2}/tests/test_admin_server.py +0 -0
  82. {dbos-0.27.1 → dbos-0.27.2}/tests/test_async.py +0 -0
  83. {dbos-0.27.1 → dbos-0.27.2}/tests/test_classdecorators.py +0 -0
  84. {dbos-0.27.1 → dbos-0.27.2}/tests/test_client.py +0 -0
  85. {dbos-0.27.1 → dbos-0.27.2}/tests/test_concurrency.py +0 -0
  86. {dbos-0.27.1 → dbos-0.27.2}/tests/test_config.py +0 -0
  87. {dbos-0.27.1 → dbos-0.27.2}/tests/test_croniter.py +0 -0
  88. {dbos-0.27.1 → dbos-0.27.2}/tests/test_dbos.py +0 -0
  89. {dbos-0.27.1 → dbos-0.27.2}/tests/test_debug.py +0 -0
  90. {dbos-0.27.1 → dbos-0.27.2}/tests/test_docker_secrets.py +0 -0
  91. {dbos-0.27.1 → dbos-0.27.2}/tests/test_failures.py +0 -0
  92. {dbos-0.27.1 → dbos-0.27.2}/tests/test_fastapi.py +0 -0
  93. {dbos-0.27.1 → dbos-0.27.2}/tests/test_fastapi_roles.py +0 -0
  94. {dbos-0.27.1 → dbos-0.27.2}/tests/test_flask.py +0 -0
  95. {dbos-0.27.1 → dbos-0.27.2}/tests/test_kafka.py +0 -0
  96. {dbos-0.27.1 → dbos-0.27.2}/tests/test_outcome.py +0 -0
  97. {dbos-0.27.1 → dbos-0.27.2}/tests/test_package.py +0 -0
  98. {dbos-0.27.1 → dbos-0.27.2}/tests/test_scheduler.py +0 -0
  99. {dbos-0.27.1 → dbos-0.27.2}/tests/test_schema_migration.py +0 -0
  100. {dbos-0.27.1 → dbos-0.27.2}/tests/test_singleton.py +0 -0
  101. {dbos-0.27.1 → dbos-0.27.2}/tests/test_spans.py +0 -0
  102. {dbos-0.27.1 → dbos-0.27.2}/tests/test_sqlalchemy.py +0 -0
  103. {dbos-0.27.1 → dbos-0.27.2}/tests/test_workflow_introspection.py +0 -0
  104. {dbos-0.27.1 → dbos-0.27.2}/tests/test_workflow_management.py +0 -0
  105. {dbos-0.27.1 → dbos-0.27.2}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.27.1
3
+ Version: 0.27.2
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1739,15 +1739,30 @@ class SystemDatabase:
1739
1739
  available_tasks = max(0, queue.concurrency - total_running_tasks)
1740
1740
  max_tasks = min(max_tasks, available_tasks)
1741
1741
 
1742
- # Lookup unstarted/uncompleted tasks (not running)
1742
+ # Retrieve the first max_tasks workflows in the queue.
1743
+ # Only retrieve workflows of the appropriate version (or without version set)
1743
1744
  query = (
1744
1745
  sa.select(
1745
1746
  SystemSchema.workflow_queue.c.workflow_uuid,
1746
1747
  )
1748
+ .select_from(
1749
+ SystemSchema.workflow_queue.join(
1750
+ SystemSchema.workflow_status,
1751
+ SystemSchema.workflow_queue.c.workflow_uuid
1752
+ == SystemSchema.workflow_status.c.workflow_uuid,
1753
+ )
1754
+ )
1747
1755
  .where(SystemSchema.workflow_queue.c.queue_name == queue.name)
1748
1756
  .where(SystemSchema.workflow_queue.c.started_at_epoch_ms == None)
1749
1757
  .where(SystemSchema.workflow_queue.c.completed_at_epoch_ms == None)
1750
1758
  .order_by(SystemSchema.workflow_queue.c.created_at_epoch_ms.asc())
1759
+ .where(
1760
+ sa.or_(
1761
+ SystemSchema.workflow_status.c.application_version
1762
+ == app_version,
1763
+ SystemSchema.workflow_status.c.application_version.is_(None),
1764
+ )
1765
+ )
1751
1766
  .with_for_update(nowait=True) # Error out early
1752
1767
  )
1753
1768
  # Apply limit only if max_tasks is finite
@@ -1779,15 +1794,6 @@ class SystemDatabase:
1779
1794
  SystemSchema.workflow_status.c.status
1780
1795
  == WorkflowStatusString.ENQUEUED.value
1781
1796
  )
1782
- .where(
1783
- sa.or_(
1784
- SystemSchema.workflow_status.c.application_version
1785
- == app_version,
1786
- SystemSchema.workflow_status.c.application_version.is_(
1787
- None
1788
- ),
1789
- )
1790
- )
1791
1797
  .values(
1792
1798
  status=WorkflowStatusString.PENDING.value,
1793
1799
  application_version=app_version,
@@ -28,7 +28,7 @@ dependencies = [
28
28
  ]
29
29
  requires-python = ">=3.9"
30
30
  readme = "README.md"
31
- version = "0.27.1"
31
+ version = "0.27.2"
32
32
 
33
33
  [project.license]
34
34
  text = "MIT"
@@ -14,6 +14,7 @@ import sqlalchemy as sa
14
14
  from dbos import (
15
15
  DBOS,
16
16
  ConfigFile,
17
+ DBOSClient,
17
18
  DBOSConfiguredInstance,
18
19
  Queue,
19
20
  SetEnqueueOptions,
@@ -1210,3 +1211,29 @@ async def test_queue_deduplication_async(dbos: DBOS) -> None:
1210
1211
  with SetWorkflowID(wfid2):
1211
1212
  handle2 = await queue.enqueue_async(test_workflow, "def")
1212
1213
  assert (await handle2.get_result()) == "def-c-p"
1214
+
1215
+ def test_worker_concurrency_across_versions(dbos: DBOS, client: DBOSClient) -> None:
1216
+ queue = Queue("test_worker_concurrency_across_versions", worker_concurrency=1)
1217
+
1218
+ @DBOS.workflow()
1219
+ def test_workflow() -> str:
1220
+ return DBOS.workflow_id
1221
+
1222
+ # First enqueue a workflow on the other version, then on the current version
1223
+ other_version = "other_version"
1224
+ other_version_handle: WorkflowHandle[None] = client.enqueue(
1225
+ {
1226
+ "queue_name": "test_worker_concurrency_across_versions",
1227
+ "workflow_name": test_workflow.__qualname__,
1228
+ "app_version": other_version,
1229
+ }
1230
+ )
1231
+ handle = queue.enqueue(test_workflow)
1232
+
1233
+ # Verify the workflow on the current version completes, but the other version is still ENQUEUED
1234
+ assert handle.get_result()
1235
+ assert other_version_handle.get_status().status == "ENQUEUED"
1236
+
1237
+ # Change the version, verify the other version complets
1238
+ GlobalParams.app_version = other_version
1239
+ assert other_version_handle.get_result()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes