horsies 0.1.0a4__py3-none-any.whl → 0.1.0a6__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.
@@ -29,6 +29,120 @@ logger = get_logger('workflow.recovery')
29
29
  _WF_TASK_TERMINAL_VALUES: list[str] = [s.value for s in WORKFLOW_TASK_TERMINAL_STATES]
30
30
 
31
31
 
32
+ GET_PENDING_WITH_TERMINAL_DEPS_SQL = text("""
33
+ SELECT wt.workflow_id, wt.task_index, wt.dependencies, wt.allow_failed_deps
34
+ FROM horsies_workflow_tasks wt
35
+ JOIN horsies_workflows w ON w.id = wt.workflow_id
36
+ WHERE wt.status = 'PENDING'
37
+ AND w.status = 'RUNNING'
38
+ AND NOT EXISTS (
39
+ SELECT 1 FROM horsies_workflow_tasks dep
40
+ WHERE dep.workflow_id = wt.workflow_id
41
+ AND dep.task_index = ANY(wt.dependencies)
42
+ AND NOT (dep.status = ANY(:wf_task_terminal_states))
43
+ )
44
+ """)
45
+
46
+ COUNT_FAILED_DEPS_SQL = text("""
47
+ SELECT COUNT(*) FROM horsies_workflow_tasks
48
+ WHERE workflow_id = :wf_id
49
+ AND task_index = ANY(:deps)
50
+ AND status IN ('FAILED', 'SKIPPED')
51
+ """)
52
+
53
+ SKIP_PENDING_TASK_SQL = text("""
54
+ UPDATE horsies_workflow_tasks
55
+ SET status = 'SKIPPED'
56
+ WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'PENDING'
57
+ """)
58
+
59
+ MARK_PENDING_READY_SQL = text("""
60
+ UPDATE horsies_workflow_tasks
61
+ SET status = 'READY'
62
+ WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'PENDING'
63
+ """)
64
+
65
+ GET_READY_NOT_ENQUEUED_SQL = text("""
66
+ SELECT wt.workflow_id, wt.task_index, wt.dependencies
67
+ FROM horsies_workflow_tasks wt
68
+ JOIN horsies_workflows w ON w.id = wt.workflow_id
69
+ WHERE wt.status = 'READY'
70
+ AND wt.task_id IS NULL
71
+ AND wt.is_subworkflow = FALSE
72
+ AND w.status = 'RUNNING'
73
+ """)
74
+
75
+ GET_READY_SUBWORKFLOWS_NOT_STARTED_SQL = text("""
76
+ SELECT wt.workflow_id, wt.task_index, wt.dependencies, w.depth, w.root_workflow_id
77
+ FROM horsies_workflow_tasks wt
78
+ JOIN horsies_workflows w ON w.id = wt.workflow_id
79
+ WHERE wt.status = 'READY'
80
+ AND wt.is_subworkflow = TRUE
81
+ AND wt.sub_workflow_id IS NULL
82
+ AND w.status = 'RUNNING'
83
+ """)
84
+
85
+ RESET_SUBWORKFLOW_TO_PENDING_SQL = text("""
86
+ UPDATE horsies_workflow_tasks
87
+ SET status = 'PENDING'
88
+ WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'READY'
89
+ """)
90
+
91
+ GET_COMPLETED_CHILDREN_NOT_UPDATED_SQL = text("""
92
+ SELECT child.id, child.parent_workflow_id, child.parent_task_index, child.status
93
+ FROM horsies_workflows child
94
+ JOIN horsies_workflows parent ON parent.id = child.parent_workflow_id
95
+ JOIN horsies_workflow_tasks wt ON wt.workflow_id = parent.id AND wt.task_index = child.parent_task_index
96
+ WHERE child.status IN ('COMPLETED', 'FAILED')
97
+ AND wt.status = 'RUNNING'
98
+ AND parent.status = 'RUNNING'
99
+ """)
100
+
101
+ GET_CRASHED_WORKER_TASKS_SQL = text("""
102
+ SELECT wt.workflow_id, wt.task_index, wt.task_id,
103
+ UPPER(t.status) as task_status, t.result as task_result
104
+ FROM horsies_workflow_tasks wt
105
+ JOIN horsies_tasks t ON t.id = wt.task_id
106
+ JOIN horsies_workflows w ON w.id = wt.workflow_id
107
+ WHERE NOT (wt.status = ANY(:wf_task_terminal_states))
108
+ AND wt.task_id IS NOT NULL
109
+ AND wt.is_subworkflow = FALSE
110
+ AND w.status = 'RUNNING'
111
+ AND UPPER(t.status) IN ('COMPLETED', 'FAILED', 'CANCELLED')
112
+ """)
113
+
114
+ GET_TERMINAL_WORKFLOW_CANDIDATES_SQL = text("""
115
+ SELECT w.id, w.error, w.success_policy,
116
+ COUNT(*) FILTER (WHERE wt.status = 'FAILED') as failed_count
117
+ FROM horsies_workflows w
118
+ LEFT JOIN horsies_workflow_tasks wt ON wt.workflow_id = w.id
119
+ WHERE w.status = 'RUNNING'
120
+ AND NOT EXISTS (
121
+ SELECT 1 FROM horsies_workflow_tasks wt2
122
+ WHERE wt2.workflow_id = w.id
123
+ AND NOT (wt2.status = ANY(:wf_task_terminal_states))
124
+ )
125
+ GROUP BY w.id, w.error, w.success_policy
126
+ """)
127
+
128
+ MARK_WORKFLOW_COMPLETED_SQL = text("""
129
+ UPDATE horsies_workflows
130
+ SET status = 'COMPLETED', result = :result, completed_at = NOW(), updated_at = NOW()
131
+ WHERE id = :wf_id AND status = 'RUNNING'
132
+ """)
133
+
134
+ MARK_WORKFLOW_FAILED_SQL = text("""
135
+ UPDATE horsies_workflows
136
+ SET status = 'FAILED', result = :result, error = :error,
137
+ completed_at = NOW(), updated_at = NOW()
138
+ WHERE id = :wf_id AND status = 'RUNNING'
139
+ """)
140
+
141
+ NOTIFY_WORKFLOW_DONE_SQL = text("""
142
+ SELECT pg_notify('workflow_done', :wf_id)
143
+ """)
144
+
145
+
32
146
  async def recover_stuck_workflows(
33
147
  session: 'AsyncSession',
34
148
  broker: 'PostgresBroker | None' = None,
@@ -56,19 +170,7 @@ async def recover_stuck_workflows(
56
170
  # This happens when multiple dependencies complete concurrently and the PENDING→READY
57
171
  # transition is missed due to timing
58
172
  pending_ready = await session.execute(
59
- text("""
60
- SELECT wt.workflow_id, wt.task_index, wt.dependencies, wt.allow_failed_deps
61
- FROM horsies_workflow_tasks wt
62
- JOIN horsies_workflows w ON w.id = wt.workflow_id
63
- WHERE wt.status = 'PENDING'
64
- AND w.status = 'RUNNING'
65
- AND NOT EXISTS (
66
- SELECT 1 FROM horsies_workflow_tasks dep
67
- WHERE dep.workflow_id = wt.workflow_id
68
- AND dep.task_index = ANY(wt.dependencies)
69
- AND NOT (dep.status = ANY(:wf_task_terminal_states))
70
- )
71
- """),
173
+ GET_PENDING_WITH_TERMINAL_DEPS_SQL,
72
174
  {'wf_task_terminal_states': _WF_TASK_TERMINAL_VALUES},
73
175
  )
74
176
 
@@ -83,12 +185,7 @@ async def recover_stuck_workflows(
83
185
 
84
186
  # Check if any dependency failed/skipped
85
187
  failed_check = await session.execute(
86
- text("""
87
- SELECT COUNT(*) FROM horsies_workflow_tasks
88
- WHERE workflow_id = :wf_id
89
- AND task_index = ANY(:deps)
90
- AND status IN ('FAILED', 'SKIPPED')
91
- """),
188
+ COUNT_FAILED_DEPS_SQL,
92
189
  {'wf_id': workflow_id, 'deps': dependencies},
93
190
  )
94
191
  failed_count = failed_check.scalar() or 0
@@ -96,11 +193,7 @@ async def recover_stuck_workflows(
96
193
  if failed_count > 0 and not allow_failed_deps:
97
194
  # Skip this task (propagate failure)
98
195
  await session.execute(
99
- text("""
100
- UPDATE horsies_workflow_tasks
101
- SET status = 'SKIPPED'
102
- WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'PENDING'
103
- """),
196
+ SKIP_PENDING_TASK_SQL,
104
197
  {'wf_id': workflow_id, 'idx': task_index},
105
198
  )
106
199
  logger.info(
@@ -111,11 +204,7 @@ async def recover_stuck_workflows(
111
204
  else:
112
205
  # Mark READY and enqueue
113
206
  await session.execute(
114
- text("""
115
- UPDATE horsies_workflow_tasks
116
- SET status = 'READY'
117
- WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'PENDING'
118
- """),
207
+ MARK_PENDING_READY_SQL,
119
208
  {'wf_id': workflow_id, 'idx': task_index},
120
209
  )
121
210
  dep_results: dict[
@@ -137,17 +226,7 @@ async def recover_stuck_workflows(
137
226
  # Case 1: READY tasks not enqueued (task_id is NULL but status is READY)
138
227
  # This happens if worker crashed after marking READY but before creating task
139
228
  # Excludes SubWorkflowNodes (handled separately)
140
- ready_not_enqueued = await session.execute(
141
- text("""
142
- SELECT wt.workflow_id, wt.task_index, wt.dependencies
143
- FROM horsies_workflow_tasks wt
144
- JOIN horsies_workflows w ON w.id = wt.workflow_id
145
- WHERE wt.status = 'READY'
146
- AND wt.task_id IS NULL
147
- AND wt.is_subworkflow = FALSE
148
- AND w.status = 'RUNNING'
149
- """)
150
- )
229
+ ready_not_enqueued = await session.execute(GET_READY_NOT_ENQUEUED_SQL)
151
230
 
152
231
  for row in ready_not_enqueued.fetchall():
153
232
  workflow_id = row[0]
@@ -177,17 +256,7 @@ async def recover_stuck_workflows(
177
256
  # Case 1.5: READY SubWorkflowNodes not started (sub_workflow_id is NULL)
178
257
  # This happens if worker crashed after marking READY but before starting child workflow
179
258
  # NOTE: This requires broker to start the child workflow, so we just mark them for retry
180
- ready_subworkflows = await session.execute(
181
- text("""
182
- SELECT wt.workflow_id, wt.task_index, wt.dependencies, w.depth, w.root_workflow_id
183
- FROM horsies_workflow_tasks wt
184
- JOIN horsies_workflows w ON w.id = wt.workflow_id
185
- WHERE wt.status = 'READY'
186
- AND wt.is_subworkflow = TRUE
187
- AND wt.sub_workflow_id IS NULL
188
- AND w.status = 'RUNNING'
189
- """)
190
- )
259
+ ready_subworkflows = await session.execute(GET_READY_SUBWORKFLOWS_NOT_STARTED_SQL)
191
260
 
192
261
  for row in ready_subworkflows.fetchall():
193
262
  workflow_id = row[0]
@@ -218,11 +287,7 @@ async def recover_stuck_workflows(
218
287
  else:
219
288
  # Reset to PENDING so a future evaluation can start it
220
289
  await session.execute(
221
- text("""
222
- UPDATE horsies_workflow_tasks
223
- SET status = 'PENDING'
224
- WHERE workflow_id = :wf_id AND task_index = :idx AND status = 'READY'
225
- """),
290
+ RESET_SUBWORKFLOW_TO_PENDING_SQL,
226
291
  {'wf_id': workflow_id, 'idx': task_index},
227
292
  )
228
293
  logger.info(
@@ -233,17 +298,7 @@ async def recover_stuck_workflows(
233
298
 
234
299
  # Case 1.6: Child workflows completed but parent node not updated
235
300
  # This happens if the _on_subworkflow_complete callback failed or was interrupted
236
- completed_children = await session.execute(
237
- text("""
238
- SELECT child.id, child.parent_workflow_id, child.parent_task_index, child.status
239
- FROM horsies_workflows child
240
- JOIN horsies_workflows parent ON parent.id = child.parent_workflow_id
241
- JOIN horsies_workflow_tasks wt ON wt.workflow_id = parent.id AND wt.task_index = child.parent_task_index
242
- WHERE child.status IN ('COMPLETED', 'FAILED')
243
- AND wt.status = 'RUNNING'
244
- AND parent.status = 'RUNNING'
245
- """)
246
- )
301
+ completed_children = await session.execute(GET_COMPLETED_CHILDREN_NOT_UPDATED_SQL)
247
302
 
248
303
  for row in completed_children.fetchall():
249
304
  child_id = row[0]
@@ -267,18 +322,7 @@ async def recover_stuck_workflows(
267
322
  # - on_workflow_task_complete() was never called (worker died)
268
323
  # - workflow_tasks row stays RUNNING/ENQUEUED indefinitely
269
324
  crashed_worker_tasks = await session.execute(
270
- text("""
271
- SELECT wt.workflow_id, wt.task_index, wt.task_id,
272
- UPPER(t.status) as task_status, t.result as task_result
273
- FROM horsies_workflow_tasks wt
274
- JOIN horsies_tasks t ON t.id = wt.task_id
275
- JOIN horsies_workflows w ON w.id = wt.workflow_id
276
- WHERE NOT (wt.status = ANY(:wf_task_terminal_states))
277
- AND wt.task_id IS NOT NULL
278
- AND wt.is_subworkflow = FALSE
279
- AND w.status = 'RUNNING'
280
- AND UPPER(t.status) IN ('COMPLETED', 'FAILED', 'CANCELLED')
281
- """),
325
+ GET_CRASHED_WORKER_TASKS_SQL,
282
326
  {'wf_task_terminal_states': _WF_TASK_TERMINAL_VALUES},
283
327
  )
284
328
 
@@ -338,19 +382,7 @@ async def recover_stuck_workflows(
338
382
  # This handles both completed and failed workflows, respecting success_policy.
339
383
  # This happens if worker crashed after completing last task but before updating workflow
340
384
  terminal_candidates = await session.execute(
341
- text("""
342
- SELECT w.id, w.error, w.success_policy,
343
- COUNT(*) FILTER (WHERE wt.status = 'FAILED') as failed_count
344
- FROM horsies_workflows w
345
- LEFT JOIN horsies_workflow_tasks wt ON wt.workflow_id = w.id
346
- WHERE w.status = 'RUNNING'
347
- AND NOT EXISTS (
348
- SELECT 1 FROM horsies_workflow_tasks wt2
349
- WHERE wt2.workflow_id = w.id
350
- AND NOT (wt2.status = ANY(:wf_task_terminal_states))
351
- )
352
- GROUP BY w.id, w.error, w.success_policy
353
- """),
385
+ GET_TERMINAL_WORKFLOW_CANDIDATES_SQL,
354
386
  {'wf_task_terminal_states': _WF_TASK_TERMINAL_VALUES},
355
387
  )
356
388
 
@@ -377,11 +409,7 @@ async def recover_stuck_workflows(
377
409
 
378
410
  if workflow_succeeded:
379
411
  await session.execute(
380
- text("""
381
- UPDATE horsies_workflows
382
- SET status = 'COMPLETED', result = :result, completed_at = NOW(), updated_at = NOW()
383
- WHERE id = :wf_id AND status = 'RUNNING'
384
- """),
412
+ MARK_WORKFLOW_COMPLETED_SQL,
385
413
  {'wf_id': workflow_id, 'result': final_result},
386
414
  )
387
415
  logger.info(f'Recovered stuck COMPLETED workflow: {workflow_id}')
@@ -394,19 +422,14 @@ async def recover_stuck_workflows(
394
422
  )
395
423
 
396
424
  await session.execute(
397
- text("""
398
- UPDATE horsies_workflows
399
- SET status = 'FAILED', result = :result, error = :error,
400
- completed_at = NOW(), updated_at = NOW()
401
- WHERE id = :wf_id AND status = 'RUNNING'
402
- """),
425
+ MARK_WORKFLOW_FAILED_SQL,
403
426
  {'wf_id': workflow_id, 'result': final_result, 'error': error_payload},
404
427
  )
405
428
  logger.info(f'Recovered stuck FAILED workflow: {workflow_id}')
406
429
 
407
430
  # Send NOTIFY for workflow completion
408
431
  await session.execute(
409
- text("SELECT pg_notify('workflow_done', :wf_id)"),
432
+ NOTIFY_WORKFLOW_DONE_SQL,
410
433
  {'wf_id': workflow_id},
411
434
  )
412
435
  recovered += 1
@@ -414,6 +437,16 @@ async def recover_stuck_workflows(
414
437
  return recovered
415
438
 
416
439
 
440
+ GET_FIRST_FAILED_TASK_RESULT_SQL = text("""
441
+ SELECT result
442
+ FROM horsies_workflow_tasks
443
+ WHERE workflow_id = :wf_id
444
+ AND status = 'FAILED'
445
+ ORDER BY task_index ASC
446
+ LIMIT 1
447
+ """)
448
+
449
+
417
450
  async def _get_first_failed_task_error(
418
451
  session: 'AsyncSession',
419
452
  workflow_id: str,
@@ -427,14 +460,7 @@ async def _get_first_failed_task_error(
427
460
  from horsies.core.codec.serde import dumps_json
428
461
 
429
462
  result = await session.execute(
430
- text("""
431
- SELECT result
432
- FROM horsies_workflow_tasks
433
- WHERE workflow_id = :wf_id
434
- AND status = 'FAILED'
435
- ORDER BY task_index ASC
436
- LIMIT 1
437
- """),
463
+ GET_FIRST_FAILED_TASK_RESULT_SQL,
438
464
  {'wf_id': workflow_id},
439
465
  )
440
466
 
@@ -449,6 +475,15 @@ async def _get_first_failed_task_error(
449
475
  return None
450
476
 
451
477
 
478
+ GET_DEPENDENCY_RESULTS_SQL = text("""
479
+ SELECT task_index, status, result
480
+ FROM horsies_workflow_tasks
481
+ WHERE workflow_id = :wf_id
482
+ AND task_index = ANY(:indices)
483
+ AND status = ANY(:wf_task_terminal_states)
484
+ """)
485
+
486
+
452
487
  async def _get_dependency_results(
453
488
  session: 'AsyncSession',
454
489
  workflow_id: str,
@@ -466,13 +501,7 @@ async def _get_dependency_results(
466
501
  return {}
467
502
 
468
503
  result = await session.execute(
469
- text("""
470
- SELECT task_index, status, result
471
- FROM horsies_workflow_tasks
472
- WHERE workflow_id = :wf_id
473
- AND task_index = ANY(:indices)
474
- AND status = ANY(:wf_task_terminal_states)
475
- """),
504
+ GET_DEPENDENCY_RESULTS_SQL,
476
505
  {
477
506
  'wf_id': workflow_id,
478
507
  'indices': dependency_indices,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: horsies
3
- Version: 0.1.0a4
3
+ Version: 0.1.0a6
4
4
  Summary: A Python library for distributed task execution
5
5
  Author: Suleyman Ozkeskin
6
6
  License-Expression: MIT
@@ -0,0 +1,42 @@
1
+ horsies/__init__.py,sha256=rLxes5IuyzggohtXKRsHoddeyqEy0LsgwDlk09itKXk,2769
2
+ horsies/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ horsies/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ horsies/core/app.py,sha256=5HkGil3sZvJAZAerRuPulKUJO-U-vgtrmQxtrVGKc2w,22218
5
+ horsies/core/banner.py,sha256=UuPylHfAutn_Vmxso2qGT_mR0iTeq6NzwBr34iOCmHE,9547
6
+ horsies/core/cli.py,sha256=irlRO9pbpGPZT7r0hSi1d0mEQkAB5M54zLb-6oB6GnY,21078
7
+ horsies/core/errors.py,sha256=3jcu4TcI1P9d2w-Tgz1yTsh4NFPOqvrd5S58cnUEKjE,16768
8
+ horsies/core/logging.py,sha256=p2utHDeOHgvwtSzKTKXh0RwUNCk38ODmgQQkmsD1tWA,2934
9
+ horsies/core/task_decorator.py,sha256=72qNptYCFs0NkVEOl24UtkCu1gAYHd79XfLYcXs37H4,29083
10
+ horsies/core/brokers/__init__.py,sha256=a_5xkHhRKY-1PRq6UidMBGq1bX-zeuSdxIvI6GdSiSQ,94
11
+ horsies/core/brokers/listener.py,sha256=pxnnAgLAWqODPV_J0XwUqAhBSrHstL77PSHYEfGoVhc,18637
12
+ horsies/core/brokers/postgres.py,sha256=KAX4oT42ku7o46R7FxoDr_jQ76zBSuN1_Za5s2QAvOk,38111
13
+ horsies/core/codec/serde.py,sha256=-dUEwyE4-DcAnP2CTbJYxBW3rOzXIUMsX_OSZSjNnpU,20043
14
+ horsies/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ horsies/core/models/app.py,sha256=d0SABV777m3UgiFCN56ZqfViagP67Kc822Ictfem4ek,12402
16
+ horsies/core/models/broker.py,sha256=yNf-tKSvJP1oIDis-jZwFMsT5exDCe27oAcnLRFSrRA,3041
17
+ horsies/core/models/queues.py,sha256=brB8rk_PQZds_VgavpZH3fkgqzsBAvRTySNNAtzikSw,699
18
+ horsies/core/models/recovery.py,sha256=9N7RYOVHewcK1Z_dUiRj4AAUtoQAOhCNLY9vXGFr7KU,5117
19
+ horsies/core/models/schedule.py,sha256=PLjxgMD_jFoLWCftuf9lVGfYhBqPHfM1FUpYguOkeWg,8284
20
+ horsies/core/models/task_pg.py,sha256=v5U1huJwASh2Saf8GDaRX-IM4mXcD8Fu43kfrFSFDLg,12304
21
+ horsies/core/models/tasks.py,sha256=qFyAZbxRAIhFLJqPgtlXO1es4eUnNzhL2X9rEKedkKA,11593
22
+ horsies/core/models/workflow.py,sha256=hv5FW-cWdH6hfC2t3rfJFf9__As4o33NYH3j8Ru7_r8,82079
23
+ horsies/core/models/workflow_pg.py,sha256=TM26UTtRC2-ulfDeEm0USRp3NYa0XDuFKGrCtmrajSg,9337
24
+ horsies/core/registry/tasks.py,sha256=mm1xb-f2HLUcZJrLgx2ZS-FQtCkuJbfsR-SW2qiMsts,3708
25
+ horsies/core/scheduler/__init__.py,sha256=m0GqCrdTbQNDUV1Fn3UZD5IewAYsV5olMrDRolg3a1I,699
26
+ horsies/core/scheduler/calculator.py,sha256=F3_9WoDKKq-1WH9Gkkne9HE4QnC_CtfsmoONPyIaXIU,8821
27
+ horsies/core/scheduler/service.py,sha256=xc0hhXlwUT3R-nIiqPzQKgYgrKHOo6qaHb5Js9J0jTw,21778
28
+ horsies/core/scheduler/state.py,sha256=B_oksOquP7rcinnRliMPEL5pAOzrdNegV-p4-VnDrYY,9222
29
+ horsies/core/types/status.py,sha256=p-SC0F-ay4oM97EqV8wHS0QimHsvftjPP1ExwheSrkA,1096
30
+ horsies/core/utils/imports.py,sha256=Tt6GTpIwGf3bIp9TZ9pYUFOS-9p_Y9cupaSLzZDLFcM,6457
31
+ horsies/core/utils/loop_runner.py,sha256=0DlbmtD8TefhyAg9edaZBHEvmze-sDj1behLKjuH4xY,1460
32
+ horsies/core/worker/current.py,sha256=UBkgevE9ulG4LFJoDlEXgpaco34qbV9Esk0tYdaBbMo,415
33
+ horsies/core/worker/worker.py,sha256=DJzkDCOo2eck7ht0QCA5cCElRvNvUJH1TiHiHis6abg,76240
34
+ horsies/core/workflows/__init__.py,sha256=JA-8wcYUHp-wF5OCEqJwKElT8PaZZB1G7iglDZ7WNiI,579
35
+ horsies/core/workflows/engine.py,sha256=ByIpZnPhQvjydVZSAJuV3Yj6eLzDfZQ3KHtPw93VojI,85894
36
+ horsies/core/workflows/recovery.py,sha256=x-jhYwIZpBxByYyFb5g2vDMtjmUFt33HgOB2J6mgPfs,19377
37
+ horsies/core/workflows/registry.py,sha256=ItpjTN8yK9NNSV8Q8OwDnHdQSO-hxDzxeWAyGvExpRk,3194
38
+ horsies-0.1.0a6.dist-info/METADATA,sha256=W3o2wh8r9BWMryc0t_Reo5D8_OwUhLtCuCaee88PCsI,1321
39
+ horsies-0.1.0a6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
40
+ horsies-0.1.0a6.dist-info/entry_points.txt,sha256=6b_OhuNbJ1ky9WSOt3UfNQXETG2YuH0lKimcibILrEE,50
41
+ horsies-0.1.0a6.dist-info/top_level.txt,sha256=ZQ_NurgT-yr3pE4a1svlO_VAhGJ6NFA31vJDLT1yyOA,8
42
+ horsies-0.1.0a6.dist-info/RECORD,,
@@ -1,42 +0,0 @@
1
- horsies/__init__.py,sha256=rLxes5IuyzggohtXKRsHoddeyqEy0LsgwDlk09itKXk,2769
2
- horsies/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- horsies/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- horsies/core/app.py,sha256=sRLVto5oFH0Mb3cwrzJXd2WoPEjoYL2ByJc764DW238,21523
5
- horsies/core/banner.py,sha256=eCp8crZZWS6JjWoTn6RtCTEpvGmkpr7hWke_Av5-bvI,5716
6
- horsies/core/cli.py,sha256=XPMRRvZqNg3ph96gWCfo0NJDOsqqe0Cuj_8Wx80sQP0,21057
7
- horsies/core/errors.py,sha256=M0PMSdsqbOMPOsZsEOmfKTvxdAD5E7BZ0IuDus7HWtk,16640
8
- horsies/core/logging.py,sha256=p2utHDeOHgvwtSzKTKXh0RwUNCk38ODmgQQkmsD1tWA,2934
9
- horsies/core/task_decorator.py,sha256=mqQYV8iLt9TwsrNQDDsBx3Vo8T5HeLFv6iiWbhF3l-c,23799
10
- horsies/core/brokers/__init__.py,sha256=a_5xkHhRKY-1PRq6UidMBGq1bX-zeuSdxIvI6GdSiSQ,94
11
- horsies/core/brokers/listener.py,sha256=pxnnAgLAWqODPV_J0XwUqAhBSrHstL77PSHYEfGoVhc,18637
12
- horsies/core/brokers/postgres.py,sha256=YZSJiQY1Spc2pNF8fjPy_0K9EAD9WAxVnFaV2P6Qf5Q,39073
13
- horsies/core/codec/serde.py,sha256=-dUEwyE4-DcAnP2CTbJYxBW3rOzXIUMsX_OSZSjNnpU,20043
14
- horsies/core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- horsies/core/models/app.py,sha256=I3HKztjNzii75bDwlbB7Jl9CPrFMfjLInUJRacQ39_s,11863
16
- horsies/core/models/broker.py,sha256=yNf-tKSvJP1oIDis-jZwFMsT5exDCe27oAcnLRFSrRA,3041
17
- horsies/core/models/queues.py,sha256=brB8rk_PQZds_VgavpZH3fkgqzsBAvRTySNNAtzikSw,699
18
- horsies/core/models/recovery.py,sha256=sI9h7Kbx_Jv23-J_0fTZRrrMgwNqmkX0-dWKTnpikvA,4964
19
- horsies/core/models/schedule.py,sha256=5mCMsX-12OPz6Gs-nr_GtaJgjxDzuyjuhSTil2XIq50,8113
20
- horsies/core/models/task_pg.py,sha256=v5U1huJwASh2Saf8GDaRX-IM4mXcD8Fu43kfrFSFDLg,12304
21
- horsies/core/models/tasks.py,sha256=nQb5z8S-GioO2aZATEvfubzqKtsNBGu-RcCn9kdituw,11592
22
- horsies/core/models/workflow.py,sha256=_93sQ-He9gbHJ4zOpmjlQ0pcRUPWGEXqzwKUNmN9gRc,71757
23
- horsies/core/models/workflow_pg.py,sha256=Nd6JDy4Htft9qQ4xKW4U2vhKNe-uUMYYZfg14t-yJnk,9315
24
- horsies/core/registry/tasks.py,sha256=mm1xb-f2HLUcZJrLgx2ZS-FQtCkuJbfsR-SW2qiMsts,3708
25
- horsies/core/scheduler/__init__.py,sha256=m0GqCrdTbQNDUV1Fn3UZD5IewAYsV5olMrDRolg3a1I,699
26
- horsies/core/scheduler/calculator.py,sha256=F3_9WoDKKq-1WH9Gkkne9HE4QnC_CtfsmoONPyIaXIU,8821
27
- horsies/core/scheduler/service.py,sha256=DNixYHbEcztHHrOK3Ud_tVIfLyFJrujCyHlqN-peBpI,21711
28
- horsies/core/scheduler/state.py,sha256=PAG2buNI2_jCIIFz4ofU4EaOTKbyNtHStM8vlmvRpIc,9211
29
- horsies/core/types/status.py,sha256=lCznEPs5NCqtMDGfC5muM34AoZ_RmtK98rIDqgMrl4Q,1074
30
- horsies/core/utils/imports.py,sha256=srIgHxxQeguMK2pNr6gama7AIqSB2embJlPpaor6hyI,6457
31
- horsies/core/utils/loop_runner.py,sha256=0DlbmtD8TefhyAg9edaZBHEvmze-sDj1behLKjuH4xY,1460
32
- horsies/core/worker/current.py,sha256=UBkgevE9ulG4LFJoDlEXgpaco34qbV9Esk0tYdaBbMo,415
33
- horsies/core/worker/worker.py,sha256=POhtTwvTjNogaXkBv4uOSD3ogb5LvuQz86A2jWmyW7I,76900
34
- horsies/core/workflows/__init__.py,sha256=JA-8wcYUHp-wF5OCEqJwKElT8PaZZB1G7iglDZ7WNiI,579
35
- horsies/core/workflows/engine.py,sha256=8Gjmch52g1IObKqzGVMWxZaZDC0diB6TuAtRfqr67l0,86927
36
- horsies/core/workflows/recovery.py,sha256=xRKQPiYaLcX4vLuvcNGy5cV14eW4Cp_sewD1nXv8gc8,19445
37
- horsies/core/workflows/registry.py,sha256=ItpjTN8yK9NNSV8Q8OwDnHdQSO-hxDzxeWAyGvExpRk,3194
38
- horsies-0.1.0a4.dist-info/METADATA,sha256=j6sZHfZ8Rzd-YEjtj2T0X2GSdrxK-2xQg8zvsZVTjqk,1321
39
- horsies-0.1.0a4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
40
- horsies-0.1.0a4.dist-info/entry_points.txt,sha256=6b_OhuNbJ1ky9WSOt3UfNQXETG2YuH0lKimcibILrEE,50
41
- horsies-0.1.0a4.dist-info/top_level.txt,sha256=ZQ_NurgT-yr3pE4a1svlO_VAhGJ6NFA31vJDLT1yyOA,8
42
- horsies-0.1.0a4.dist-info/RECORD,,