dbos 0.23.0a2__tar.gz → 0.23.0a3__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 (92) hide show
  1. {dbos-0.23.0a2 → dbos-0.23.0a3}/PKG-INFO +1 -1
  2. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_recovery.py +1 -0
  3. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_sys_db.py +1 -0
  4. {dbos-0.23.0a2 → dbos-0.23.0a3}/pyproject.toml +1 -1
  5. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_admin_server.py +30 -22
  6. {dbos-0.23.0a2 → dbos-0.23.0a3}/LICENSE +0 -0
  7. {dbos-0.23.0a2 → dbos-0.23.0a3}/README.md +0 -0
  8. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/__init__.py +0 -0
  9. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_admin_server.py +0 -0
  10. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_app_db.py +0 -0
  11. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_classproperty.py +0 -0
  12. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_cloudutils/authentication.py +0 -0
  13. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_cloudutils/cloudutils.py +0 -0
  14. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_cloudutils/databases.py +0 -0
  15. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_context.py +0 -0
  16. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_core.py +0 -0
  17. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_croniter.py +0 -0
  18. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_db_wizard.py +0 -0
  19. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_dbos.py +0 -0
  20. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_dbos_config.py +0 -0
  21. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_error.py +0 -0
  22. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_fastapi.py +0 -0
  23. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_flask.py +0 -0
  24. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_kafka.py +0 -0
  25. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_kafka_message.py +0 -0
  26. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_logger.py +0 -0
  27. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/env.py +0 -0
  28. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/script.py.mako +0 -0
  29. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/04ca4f231047_workflow_queues_executor_id.py +0 -0
  30. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/50f3227f0b4b_fix_job_queue.py +0 -0
  31. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/5c361fc04708_added_system_tables.py +0 -0
  32. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/a3b18ad34abe_added_triggers.py +0 -0
  33. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/d76646551a6b_job_queue_limiter.py +0 -0
  34. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/d76646551a6c_workflow_queue.py +0 -0
  35. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_migrations/versions/eab0cc1d9a14_job_queue.py +0 -0
  36. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_outcome.py +0 -0
  37. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_queue.py +0 -0
  38. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_registrations.py +0 -0
  39. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_request.py +0 -0
  40. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_roles.py +0 -0
  41. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_scheduler.py +0 -0
  42. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_schemas/__init__.py +0 -0
  43. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_schemas/application_database.py +0 -0
  44. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_schemas/system_database.py +0 -0
  45. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_serialization.py +0 -0
  46. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/README.md +0 -0
  47. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/__package/__init__.py +0 -0
  48. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/__package/main.py +0 -0
  49. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/__package/schema.py +0 -0
  50. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/alembic.ini +0 -0
  51. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/dbos-config.yaml.dbos +0 -0
  52. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/migrations/env.py.dbos +0 -0
  53. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/migrations/script.py.mako +0 -0
  54. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/migrations/versions/2024_07_31_180642_init.py +0 -0
  55. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_templates/dbos-db-starter/start_postgres_docker.py +0 -0
  56. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_tracer.py +0 -0
  57. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_utils.py +0 -0
  58. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/_workflow_commands.py +0 -0
  59. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/cli/_github_init.py +0 -0
  60. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/cli/_template_init.py +0 -0
  61. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/cli/cli.py +0 -0
  62. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/dbos-config.schema.json +0 -0
  63. {dbos-0.23.0a2 → dbos-0.23.0a3}/dbos/py.typed +0 -0
  64. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/__init__.py +0 -0
  65. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/atexit_no_ctor.py +0 -0
  66. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/atexit_no_launch.py +0 -0
  67. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/classdefs.py +0 -0
  68. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/conftest.py +0 -0
  69. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/more_classdefs.py +0 -0
  70. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/queuedworkflow.py +0 -0
  71. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_async.py +0 -0
  72. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_classdecorators.py +0 -0
  73. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_concurrency.py +0 -0
  74. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_config.py +0 -0
  75. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_croniter.py +0 -0
  76. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_dbos.py +0 -0
  77. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_failures.py +0 -0
  78. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_fastapi.py +0 -0
  79. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_fastapi_roles.py +0 -0
  80. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_flask.py +0 -0
  81. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_kafka.py +0 -0
  82. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_outcome.py +0 -0
  83. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_package.py +0 -0
  84. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_queue.py +0 -0
  85. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_scheduler.py +0 -0
  86. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_schema_migration.py +0 -0
  87. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_singleton.py +0 -0
  88. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_spans.py +0 -0
  89. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_sqlalchemy.py +0 -0
  90. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_workflow_cancel.py +0 -0
  91. {dbos-0.23.0a2 → dbos-0.23.0a3}/tests/test_workflow_cmds.py +0 -0
  92. {dbos-0.23.0a2 → dbos-0.23.0a3}/version/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.23.0a2
3
+ Version: 0.23.0a3
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -43,6 +43,7 @@ def startup_recovery_thread(
43
43
  def recover_pending_workflows(
44
44
  dbos: "DBOS", executor_ids: List[str] = ["local"]
45
45
  ) -> List["WorkflowHandle[Any]"]:
46
+ """Attempt to recover pending workflows for a list of specific executors and return workflow handles for them."""
46
47
  workflow_handles: List["WorkflowHandle[Any]"] = []
47
48
  for executor_id in executor_ids:
48
49
  dbos.logger.debug(f"Recovering pending workflows for executor: {executor_id}")
@@ -305,6 +305,7 @@ class SystemDatabase:
305
305
  .on_conflict_do_update(
306
306
  index_elements=["workflow_uuid"],
307
307
  set_=dict(
308
+ executor_id=status["executor_id"],
308
309
  recovery_attempts=(
309
310
  SystemSchema.workflow_status.c.recovery_attempts + 1
310
311
  ),
@@ -27,7 +27,7 @@ dependencies = [
27
27
  ]
28
28
  requires-python = ">=3.9"
29
29
  readme = "README.md"
30
- version = "0.23.0a2"
30
+ version = "0.23.0a3"
31
31
 
32
32
  [project.license]
33
33
  text = "MIT"
@@ -3,9 +3,12 @@ import time
3
3
  import uuid
4
4
 
5
5
  import requests
6
+ import sqlalchemy as sa
6
7
 
7
8
  # Public API
8
9
  from dbos import DBOS, ConfigFile, Queue, SetWorkflowID, _workflow_commands
10
+ from dbos._schemas.system_database import SystemSchema
11
+ from dbos._sys_db import WorkflowStatusString
9
12
  from dbos._utils import GlobalParams
10
13
 
11
14
 
@@ -91,34 +94,25 @@ def test_admin_recovery(config: ConfigFile) -> None:
91
94
  assert test_workflow("bob", "bob") == "bob1bob"
92
95
 
93
96
  dbos._sys_db.wait_for_buffer_flush()
94
- # Change the workflow status to pending
95
- dbos._sys_db.update_workflow_status(
96
- {
97
- "workflow_uuid": wfuuid,
98
- "status": "PENDING",
99
- "name": test_workflow.__qualname__,
100
- "class_name": None,
101
- "config_name": None,
102
- "output": None,
103
- "error": None,
104
- "executor_id": None,
105
- "app_id": None,
106
- "app_version": None,
107
- "request": None,
108
- "recovery_attempts": None,
109
- "authenticated_user": None,
110
- "authenticated_roles": None,
111
- "assumed_role": None,
112
- "queue_name": None,
113
- }
114
- )
97
+
98
+ # Manually update the database to pretend the workflow comes from another executor and is pending
99
+ with dbos._sys_db.engine.begin() as c:
100
+ query = (
101
+ sa.update(SystemSchema.workflow_status)
102
+ .values(
103
+ status=WorkflowStatusString.PENDING.value, executor_id="other-executor"
104
+ )
105
+ .where(SystemSchema.workflow_status.c.workflow_uuid == wfuuid)
106
+ )
107
+ c.execute(query)
108
+
115
109
  status = dbos.get_workflow_status(wfuuid)
116
110
  assert (
117
111
  status is not None and status.status == "PENDING"
118
112
  ), "Workflow status not updated"
119
113
 
120
114
  # Test POST /dbos-workflow-recovery
121
- data = ["testexecutor"]
115
+ data = ["other-executor"]
122
116
  response = requests.post(
123
117
  "http://localhost:3001/dbos-workflow-recovery", json=data, timeout=5
124
118
  )
@@ -131,6 +125,8 @@ def test_admin_recovery(config: ConfigFile) -> None:
131
125
  for attempt in range(max_retries):
132
126
  status = dbos.get_workflow_status(wfuuid)
133
127
  if status is not None and status.status == "SUCCESS":
128
+ assert status.status == "SUCCESS"
129
+ assert status.executor_id == "testexecutor"
134
130
  succeeded = True
135
131
  break
136
132
  else:
@@ -208,6 +204,17 @@ def test_admin_workflow_resume(dbos: DBOS, config: ConfigFile) -> None:
208
204
  assert info is not None
209
205
  assert info.status == "CANCELLED", f"Expected status to be CANCELLED"
210
206
 
207
+ # Manually update the database to pretend the workflow comes from another executor and is pending
208
+ with dbos._sys_db.engine.begin() as c:
209
+ query = (
210
+ sa.update(SystemSchema.workflow_status)
211
+ .values(
212
+ status=WorkflowStatusString.PENDING.value, executor_id="other-executor"
213
+ )
214
+ .where(SystemSchema.workflow_status.c.workflow_uuid == wfUuid)
215
+ )
216
+ c.execute(query)
217
+
211
218
  # Resume the workflow. Verify that it succeeds again.
212
219
  response = requests.post(
213
220
  f"http://localhost:3001/workflows/{wfUuid}/resume", json=[], timeout=5
@@ -218,6 +225,7 @@ def test_admin_workflow_resume(dbos: DBOS, config: ConfigFile) -> None:
218
225
  info = _workflow_commands.get_workflow(config, wfUuid, True)
219
226
  assert info is not None
220
227
  assert info.status == "SUCCESS", f"Expected status to be SUCCESS"
228
+ assert info.executor_id == GlobalParams.executor_id
221
229
 
222
230
  # Resume the workflow. Verify it does not run and status remains SUCCESS
223
231
  response = requests.post(
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