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.
- dbos/_conductor/conductor.py +84 -48
- dbos/_conductor/protocol.py +14 -0
- {dbos-0.24.0a7.dist-info → dbos-0.24.0a8.dist-info}/METADATA +1 -1
- {dbos-0.24.0a7.dist-info → dbos-0.24.0a8.dist-info}/RECORD +7 -7
- {dbos-0.24.0a7.dist-info → dbos-0.24.0a8.dist-info}/WHEEL +0 -0
- {dbos-0.24.0a7.dist-info → dbos-0.24.0a8.dist-info}/entry_points.txt +0 -0
- {dbos-0.24.0a7.dist-info → dbos-0.24.0a8.dist-info}/licenses/LICENSE +0 -0
dbos/_conductor/conductor.py
CHANGED
|
@@ -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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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
|
-
|
|
97
|
-
|
|
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
|
-
|
|
113
|
-
|
|
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 =
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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 =
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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 =
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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 =
|
|
202
|
-
|
|
203
|
-
|
|
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
|
dbos/_conductor/protocol.py
CHANGED
|
@@ -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,7 +1,7 @@
|
|
|
1
|
-
dbos-0.24.
|
|
2
|
-
dbos-0.24.
|
|
3
|
-
dbos-0.24.
|
|
4
|
-
dbos-0.24.
|
|
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=
|
|
14
|
-
dbos/_conductor/protocol.py,sha256=
|
|
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.
|
|
68
|
+
dbos-0.24.0a8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|