dbos 0.24.0a7__py3-none-any.whl → 0.24.0a8__py3-none-any.whl

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.

Potentially problematic release.


This version of dbos might be problematic. Click here for more details.

@@ -33,7 +33,7 @@ class ConductorWebsocket(threading.Thread):
33
33
  def run(self) -> None:
34
34
  while not self.evt.is_set():
35
35
  try:
36
- with connect(self.url) as websocket:
36
+ with connect(self.url, open_timeout=5) as websocket:
37
37
  self.websocket = websocket
38
38
  while not self.evt.is_set():
39
39
  message = websocket.recv()
@@ -44,6 +44,7 @@ class ConductorWebsocket(threading.Thread):
44
44
  continue
45
45
  base_message = p.BaseMessage.from_json(message)
46
46
  msg_type = base_message.type
47
+ error_message = None
47
48
  if msg_type == p.MessageType.EXECUTOR_INFO:
48
49
  info_response = p.ExecutorInfoResponse(
49
50
  type=p.MessageType.EXECUTOR_INFO,
@@ -61,14 +62,14 @@ class ConductorWebsocket(threading.Thread):
61
62
  recovery_message.executor_ids
62
63
  )
63
64
  except Exception as e:
64
- self.dbos.logger.error(
65
- f"Exception encountered when recovering workflows: {traceback.format_exc()}"
66
- )
65
+ error_message = f"Exception encountered when recovering workflows: {traceback.format_exc()}"
66
+ self.dbos.logger.error(error_message)
67
67
  success = False
68
68
  recovery_response = p.RecoveryResponse(
69
69
  type=p.MessageType.RECOVERY,
70
70
  request_id=base_message.request_id,
71
71
  success=success,
72
+ error_message=error_message,
72
73
  )
73
74
  websocket.send(recovery_response.to_json())
74
75
  elif msg_type == p.MessageType.CANCEL:
@@ -77,14 +78,14 @@ class ConductorWebsocket(threading.Thread):
77
78
  try:
78
79
  self.dbos.cancel_workflow(cancel_message.workflow_id)
79
80
  except Exception as e:
80
- self.dbos.logger.error(
81
- f"Exception encountered when cancelling workflow {cancel_message.workflow_id}: {traceback.format_exc()}"
82
- )
81
+ error_message = f"Exception encountered when cancelling workflow {cancel_message.workflow_id}: {traceback.format_exc()}"
82
+ self.dbos.logger.error(error_message)
83
83
  success = False
84
84
  cancel_response = p.CancelResponse(
85
85
  type=p.MessageType.CANCEL,
86
86
  request_id=base_message.request_id,
87
87
  success=success,
88
+ error_message=error_message,
88
89
  )
89
90
  websocket.send(cancel_response.to_json())
90
91
  elif msg_type == p.MessageType.RESUME:
@@ -93,14 +94,14 @@ class ConductorWebsocket(threading.Thread):
93
94
  try:
94
95
  self.dbos.resume_workflow(resume_message.workflow_id)
95
96
  except Exception as e:
96
- self.dbos.logger.error(
97
- f"Exception encountered when resuming workflow {resume_message.workflow_id}: {traceback.format_exc()}"
98
- )
97
+ error_message = f"Exception encountered when resuming workflow {resume_message.workflow_id}: {traceback.format_exc()}"
98
+ self.dbos.logger.error(error_message)
99
99
  success = False
100
100
  resume_response = p.ResumeResponse(
101
101
  type=p.MessageType.RESUME,
102
102
  request_id=base_message.request_id,
103
103
  success=success,
104
+ error_message=error_message,
104
105
  )
105
106
  websocket.send(resume_response.to_json())
106
107
  elif msg_type == p.MessageType.RESTART:
@@ -109,14 +110,14 @@ class ConductorWebsocket(threading.Thread):
109
110
  try:
110
111
  self.dbos.restart_workflow(restart_message.workflow_id)
111
112
  except Exception as e:
112
- self.dbos.logger.error(
113
- f"Exception encountered when restarting workflow {restart_message.workflow_id}: {traceback.format_exc()}"
114
- )
113
+ error_message = f"Exception encountered when restarting workflow {restart_message.workflow_id}: {traceback.format_exc()}"
114
+ self.dbos.logger.error(error_message)
115
115
  success = False
116
116
  restart_response = p.RestartResponse(
117
117
  type=p.MessageType.RESTART,
118
118
  request_id=base_message.request_id,
119
119
  success=success,
120
+ error_message=error_message,
120
121
  )
121
122
  websocket.send(restart_response.to_json())
122
123
  elif msg_type == p.MessageType.LIST_WORKFLOWS:
@@ -124,20 +125,26 @@ class ConductorWebsocket(threading.Thread):
124
125
  message
125
126
  )
126
127
  body = list_workflows_message.body
127
- infos = list_workflows(
128
- self.dbos._sys_db,
129
- workflow_ids=body["workflow_uuids"],
130
- user=body["authenticated_user"],
131
- start_time=body["start_time"],
132
- end_time=body["end_time"],
133
- status=body["status"],
134
- request=False,
135
- app_version=body["application_version"],
136
- name=body["workflow_name"],
137
- limit=body["limit"],
138
- offset=body["offset"],
139
- sort_desc=body["sort_desc"],
140
- )
128
+ infos = []
129
+ try:
130
+ infos = list_workflows(
131
+ self.dbos._sys_db,
132
+ workflow_ids=body["workflow_uuids"],
133
+ user=body["authenticated_user"],
134
+ start_time=body["start_time"],
135
+ end_time=body["end_time"],
136
+ status=body["status"],
137
+ request=False,
138
+ app_version=body["application_version"],
139
+ name=body["workflow_name"],
140
+ limit=body["limit"],
141
+ offset=body["offset"],
142
+ sort_desc=body["sort_desc"],
143
+ )
144
+ except Exception as e:
145
+ error_message = f"Exception encountered when listing workflows: {traceback.format_exc()}"
146
+ self.dbos.logger.error(error_message)
147
+
141
148
  list_workflows_response = p.ListWorkflowsResponse(
142
149
  type=p.MessageType.LIST_WORKFLOWS,
143
150
  request_id=base_message.request_id,
@@ -145,6 +152,7 @@ class ConductorWebsocket(threading.Thread):
145
152
  p.WorkflowsOutput.from_workflow_information(i)
146
153
  for i in infos
147
154
  ],
155
+ error_message=error_message,
148
156
  )
149
157
  websocket.send(list_workflows_response.to_json())
150
158
  elif msg_type == p.MessageType.LIST_QUEUED_WORKFLOWS:
@@ -152,18 +160,24 @@ class ConductorWebsocket(threading.Thread):
152
160
  p.ListQueuedWorkflowsRequest.from_json(message)
153
161
  )
154
162
  q_body = list_queued_workflows_message.body
155
- infos = list_queued_workflows(
156
- self.dbos._sys_db,
157
- start_time=q_body["start_time"],
158
- end_time=q_body["end_time"],
159
- status=q_body["status"],
160
- request=False,
161
- name=q_body["workflow_name"],
162
- limit=q_body["limit"],
163
- offset=q_body["offset"],
164
- queue_name=q_body["queue_name"],
165
- sort_desc=q_body["sort_desc"],
166
- )
163
+ infos = []
164
+ try:
165
+ infos = list_queued_workflows(
166
+ self.dbos._sys_db,
167
+ start_time=q_body["start_time"],
168
+ end_time=q_body["end_time"],
169
+ status=q_body["status"],
170
+ request=False,
171
+ name=q_body["workflow_name"],
172
+ limit=q_body["limit"],
173
+ offset=q_body["offset"],
174
+ queue_name=q_body["queue_name"],
175
+ sort_desc=q_body["sort_desc"],
176
+ )
177
+ except Exception as e:
178
+ error_message = f"Exception encountered when listing queued workflows: {traceback.format_exc()}"
179
+ self.dbos.logger.error(error_message)
180
+
167
181
  list_queued_workflows_response = (
168
182
  p.ListQueuedWorkflowsResponse(
169
183
  type=p.MessageType.LIST_QUEUED_WORKFLOWS,
@@ -172,6 +186,7 @@ class ConductorWebsocket(threading.Thread):
172
186
  p.WorkflowsOutput.from_workflow_information(i)
173
187
  for i in infos
174
188
  ],
189
+ error_message=error_message,
175
190
  )
176
191
  )
177
192
  websocket.send(list_queued_workflows_response.to_json())
@@ -179,11 +194,17 @@ class ConductorWebsocket(threading.Thread):
179
194
  get_workflow_message = p.GetWorkflowRequest.from_json(
180
195
  message
181
196
  )
182
- info = get_workflow(
183
- self.dbos._sys_db,
184
- get_workflow_message.workflow_id,
185
- getRequest=False,
186
- )
197
+ info = None
198
+ try:
199
+ info = get_workflow(
200
+ self.dbos._sys_db,
201
+ get_workflow_message.workflow_id,
202
+ getRequest=False,
203
+ )
204
+ except Exception as e:
205
+ error_message = f"Exception encountered when getting workflow {get_workflow_message.workflow_id}: {traceback.format_exc()}"
206
+ self.dbos.logger.error(error_message)
207
+
187
208
  get_workflow_response = p.GetWorkflowResponse(
188
209
  type=p.MessageType.GET_WORKFLOW,
189
210
  request_id=base_message.request_id,
@@ -192,21 +213,29 @@ class ConductorWebsocket(threading.Thread):
192
213
  if info is not None
193
214
  else None
194
215
  ),
216
+ error_message=error_message,
195
217
  )
196
218
  websocket.send(get_workflow_response.to_json())
197
219
  elif msg_type == p.MessageType.EXIST_PENDING_WORKFLOWS:
198
220
  exist_pending_workflows_message = (
199
221
  p.ExistPendingWorkflowsRequest.from_json(message)
200
222
  )
201
- pending_wfs = self.dbos._sys_db.get_pending_workflows(
202
- exist_pending_workflows_message.executor_id,
203
- exist_pending_workflows_message.application_version,
204
- )
223
+ pending_wfs = []
224
+ try:
225
+ pending_wfs = self.dbos._sys_db.get_pending_workflows(
226
+ exist_pending_workflows_message.executor_id,
227
+ exist_pending_workflows_message.application_version,
228
+ )
229
+ except Exception as e:
230
+ error_message = f"Exception encountered when checking for pending workflows: {traceback.format_exc()}"
231
+ self.dbos.logger.error(error_message)
232
+
205
233
  exist_pending_workflows_response = (
206
234
  p.ExistPendingWorkflowsResponse(
207
235
  type=p.MessageType.EXIST_PENDING_WORKFLOWS,
208
236
  request_id=base_message.request_id,
209
237
  exist=len(pending_wfs) > 0,
238
+ error_message=error_message,
210
239
  )
211
240
  )
212
241
  websocket.send(exist_pending_workflows_response.to_json())
@@ -214,6 +243,13 @@ class ConductorWebsocket(threading.Thread):
214
243
  self.dbos.logger.warning(
215
244
  f"Unexpected message type: {msg_type}"
216
245
  )
246
+ unknown_message = p.BaseResponse(
247
+ request_id=base_message.request_id,
248
+ type=msg_type,
249
+ error_message="Unknown message type",
250
+ )
251
+ # Still need to send a response to the conductor
252
+ websocket.send(unknown_message.to_json())
217
253
  except ConnectionClosedOK:
218
254
  self.dbos.logger.info("Conductor connection terminated")
219
255
  break
@@ -45,6 +45,11 @@ class BaseMessage:
45
45
  return json.dumps(dict_data)
46
46
 
47
47
 
48
+ @dataclass
49
+ class BaseResponse(BaseMessage):
50
+ error_message: Optional[str] = None
51
+
52
+
48
53
  @dataclass
49
54
  class ExecutorInfoRequest(BaseMessage):
50
55
  pass
@@ -54,6 +59,7 @@ class ExecutorInfoRequest(BaseMessage):
54
59
  class ExecutorInfoResponse(BaseMessage):
55
60
  executor_id: str
56
61
  application_version: str
62
+ error_message: Optional[str] = None
57
63
 
58
64
 
59
65
  @dataclass
@@ -64,6 +70,7 @@ class RecoveryRequest(BaseMessage):
64
70
  @dataclass
65
71
  class RecoveryResponse(BaseMessage):
66
72
  success: bool
73
+ error_message: Optional[str] = None
67
74
 
68
75
 
69
76
  @dataclass
@@ -74,6 +81,7 @@ class CancelRequest(BaseMessage):
74
81
  @dataclass
75
82
  class CancelResponse(BaseMessage):
76
83
  success: bool
84
+ error_message: Optional[str] = None
77
85
 
78
86
 
79
87
  @dataclass
@@ -84,6 +92,7 @@ class ResumeRequest(BaseMessage):
84
92
  @dataclass
85
93
  class ResumeResponse(BaseMessage):
86
94
  success: bool
95
+ error_message: Optional[str] = None
87
96
 
88
97
 
89
98
  @dataclass
@@ -94,6 +103,7 @@ class RestartRequest(BaseMessage):
94
103
  @dataclass
95
104
  class RestartResponse(BaseMessage):
96
105
  success: bool
106
+ error_message: Optional[str] = None
97
107
 
98
108
 
99
109
  class ListWorkflowsBody(TypedDict):
@@ -165,6 +175,7 @@ class ListWorkflowsRequest(BaseMessage):
165
175
  @dataclass
166
176
  class ListWorkflowsResponse(BaseMessage):
167
177
  output: List[WorkflowsOutput]
178
+ error_message: Optional[str] = None
168
179
 
169
180
 
170
181
  class ListQueuedWorkflowsBody(TypedDict):
@@ -186,6 +197,7 @@ class ListQueuedWorkflowsRequest(BaseMessage):
186
197
  @dataclass
187
198
  class ListQueuedWorkflowsResponse(BaseMessage):
188
199
  output: List[WorkflowsOutput]
200
+ error_message: Optional[str] = None
189
201
 
190
202
 
191
203
  @dataclass
@@ -196,6 +208,7 @@ class GetWorkflowRequest(BaseMessage):
196
208
  @dataclass
197
209
  class GetWorkflowResponse(BaseMessage):
198
210
  output: Optional[WorkflowsOutput]
211
+ error_message: Optional[str] = None
199
212
 
200
213
 
201
214
  @dataclass
@@ -207,3 +220,4 @@ class ExistPendingWorkflowsRequest(BaseMessage):
207
220
  @dataclass
208
221
  class ExistPendingWorkflowsResponse(BaseMessage):
209
222
  exist: bool
223
+ error_message: Optional[str] = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dbos
3
- Version: 0.24.0a7
3
+ Version: 0.24.0a8
4
4
  Summary: Ultra-lightweight durable execution in Python
5
5
  Author-Email: "DBOS, Inc." <contact@dbos.dev>
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
- dbos-0.24.0a7.dist-info/METADATA,sha256=wvDZ3P2eE7j7S3YM33RoAxO3Sp0R9woyTrAC1wCEvdE,5555
2
- dbos-0.24.0a7.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- dbos-0.24.0a7.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
- dbos-0.24.0a7.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
1
+ dbos-0.24.0a8.dist-info/METADATA,sha256=XsFBfl6GM7-vBod-qlcQ0QphxHaMNGPaeYloFB02pLE,5555
2
+ dbos-0.24.0a8.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ dbos-0.24.0a8.dist-info/entry_points.txt,sha256=_QOQ3tVfEjtjBlr1jS4sHqHya9lI2aIEIWkz8dqYp14,58
4
+ dbos-0.24.0a8.dist-info/licenses/LICENSE,sha256=VGZit_a5-kdw9WT6fY5jxAWVwGQzgLFyPWrcVVUhVNU,1067
5
5
  dbos/__init__.py,sha256=uq9LP5uY96kIS9N0yKqlvDwADmtg_Hl30uSUhyuUr-4,754
6
6
  dbos/__main__.py,sha256=P7jAr-7L9XE5mrsQ7i4b-bLr2ap1tCQfhMByLCRWDj0,568
7
7
  dbos/_admin_server.py,sha256=YiVn5lywz2Vg8_juyNHOYl0HVEy48--7b4phwK7r92o,5732
@@ -10,8 +10,8 @@ dbos/_classproperty.py,sha256=f0X-_BySzn3yFDRKB2JpCbLYQ9tLwt1XftfshvY7CBs,626
10
10
  dbos/_cloudutils/authentication.py,sha256=V0fCWQN9stCkhbuuxgPTGpvuQcDqfU3KAxPAh01vKW4,5007
11
11
  dbos/_cloudutils/cloudutils.py,sha256=YC7jGsIopT0KveLsqbRpQk2KlRBk-nIRC_UCgep4f3o,7797
12
12
  dbos/_cloudutils/databases.py,sha256=_shqaqSvhY4n2ScgQ8IP5PDZvzvcx3YBKV8fj-cxhSY,8543
13
- dbos/_conductor/conductor.py,sha256=tvB1k8V3ZsI3MBEcG9sIkfbsHHx_Cvh0FZAi9vSPrXU,12698
14
- dbos/_conductor/protocol.py,sha256=Lo-DjvKevTS2uKyITLjjVp56rBRzaQfKkKpieZz3VAs,5088
13
+ dbos/_conductor/conductor.py,sha256=5mFrE6yEAHWcFjkYr5p2AoPkV6iwYHxsB3K06yaOmqM,15112
14
+ dbos/_conductor/protocol.py,sha256=W-BnX-bD5folo96NGrUytuCHW72H-OQwPrkJ9q5Au5c,5534
15
15
  dbos/_context.py,sha256=Ue5qu3rzLfRmPkz-UUZi9ZS8iXpapRN0NTM4mbA2QmQ,17738
16
16
  dbos/_core.py,sha256=8TTIj5shcm5hpKjouMA4VzMWl7R7MJlU-mAHB6xQBxE,37585
17
17
  dbos/_croniter.py,sha256=XHAyUyibs_59sJQfSNWkP7rqQY6_XrlfuuCxk4jYqek,47559
@@ -65,4 +65,4 @@ dbos/cli/cli.py,sha256=ThomRytw7EP5iOcrjEgwnpaWgXNTLfnFEBBvCGHxtJs,15590
65
65
  dbos/dbos-config.schema.json,sha256=HtF_njVTGHLdzBGZ4OrGQz3qbPPT0Go-iwd1PgFVTNg,5847
66
66
  dbos/py.typed,sha256=QfzXT1Ktfk3Rj84akygc7_42z0lRpCq0Ilh8OXI6Zas,44
67
67
  version/__init__.py,sha256=L4sNxecRuqdtSFdpUGX3TtBi9KL3k7YsZVIvv-fv9-A,1678
68
- dbos-0.24.0a7.dist-info/RECORD,,
68
+ dbos-0.24.0a8.dist-info/RECORD,,