hatchet-sdk 1.12.3__py3-none-any.whl → 1.14.0__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 hatchet-sdk might be problematic. Click here for more details.
- hatchet_sdk/__init__.py +54 -40
- hatchet_sdk/clients/admin.py +18 -23
- hatchet_sdk/clients/dispatcher/action_listener.py +4 -3
- hatchet_sdk/clients/dispatcher/dispatcher.py +1 -4
- hatchet_sdk/clients/event_ts.py +2 -1
- hatchet_sdk/clients/events.py +16 -12
- hatchet_sdk/clients/listeners/durable_event_listener.py +4 -2
- hatchet_sdk/clients/listeners/pooled_listener.py +2 -2
- hatchet_sdk/clients/listeners/run_event_listener.py +7 -8
- hatchet_sdk/clients/listeners/workflow_listener.py +14 -6
- hatchet_sdk/clients/rest/api_response.py +3 -2
- hatchet_sdk/clients/rest/models/semaphore_slots.py +1 -1
- hatchet_sdk/clients/rest/models/v1_task_summary.py +5 -0
- hatchet_sdk/clients/rest/models/v1_workflow_run_details.py +11 -1
- hatchet_sdk/clients/rest/models/workflow_version.py +5 -0
- hatchet_sdk/clients/rest/tenacity_utils.py +6 -8
- hatchet_sdk/config.py +2 -0
- hatchet_sdk/connection.py +10 -4
- hatchet_sdk/context/context.py +170 -46
- hatchet_sdk/context/worker_context.py +4 -7
- hatchet_sdk/contracts/dispatcher_pb2.py +38 -38
- hatchet_sdk/contracts/dispatcher_pb2.pyi +4 -2
- hatchet_sdk/contracts/events_pb2.py +13 -13
- hatchet_sdk/contracts/events_pb2.pyi +4 -2
- hatchet_sdk/contracts/v1/workflows_pb2.py +1 -1
- hatchet_sdk/contracts/v1/workflows_pb2.pyi +2 -2
- hatchet_sdk/exceptions.py +103 -1
- hatchet_sdk/features/cron.py +2 -2
- hatchet_sdk/features/filters.py +12 -21
- hatchet_sdk/features/runs.py +4 -4
- hatchet_sdk/features/scheduled.py +8 -9
- hatchet_sdk/hatchet.py +65 -64
- hatchet_sdk/opentelemetry/instrumentor.py +20 -20
- hatchet_sdk/runnables/action.py +1 -2
- hatchet_sdk/runnables/contextvars.py +19 -0
- hatchet_sdk/runnables/task.py +37 -29
- hatchet_sdk/runnables/types.py +9 -8
- hatchet_sdk/runnables/workflow.py +57 -42
- hatchet_sdk/utils/proto_enums.py +4 -4
- hatchet_sdk/utils/timedelta_to_expression.py +2 -3
- hatchet_sdk/utils/typing.py +11 -17
- hatchet_sdk/v0/__init__.py +7 -7
- hatchet_sdk/v0/clients/admin.py +7 -7
- hatchet_sdk/v0/clients/dispatcher/action_listener.py +8 -8
- hatchet_sdk/v0/clients/dispatcher/dispatcher.py +9 -9
- hatchet_sdk/v0/clients/events.py +3 -3
- hatchet_sdk/v0/clients/rest/tenacity_utils.py +1 -1
- hatchet_sdk/v0/clients/run_event_listener.py +3 -3
- hatchet_sdk/v0/clients/workflow_listener.py +5 -5
- hatchet_sdk/v0/context/context.py +6 -6
- hatchet_sdk/v0/hatchet.py +4 -4
- hatchet_sdk/v0/opentelemetry/instrumentor.py +1 -1
- hatchet_sdk/v0/rate_limit.py +1 -1
- hatchet_sdk/v0/v2/callable.py +4 -4
- hatchet_sdk/v0/v2/concurrency.py +2 -2
- hatchet_sdk/v0/v2/hatchet.py +3 -3
- hatchet_sdk/v0/worker/action_listener_process.py +6 -6
- hatchet_sdk/v0/worker/runner/run_loop_manager.py +1 -1
- hatchet_sdk/v0/worker/runner/runner.py +10 -10
- hatchet_sdk/v0/worker/runner/utils/capture_logs.py +1 -1
- hatchet_sdk/v0/worker/worker.py +2 -2
- hatchet_sdk/v0/workflow.py +3 -3
- hatchet_sdk/waits.py +6 -5
- hatchet_sdk/worker/action_listener_process.py +33 -13
- hatchet_sdk/worker/runner/run_loop_manager.py +15 -11
- hatchet_sdk/worker/runner/runner.py +142 -80
- hatchet_sdk/worker/runner/utils/capture_logs.py +72 -31
- hatchet_sdk/worker/worker.py +30 -26
- hatchet_sdk/workflow_run.py +4 -2
- {hatchet_sdk-1.12.3.dist-info → hatchet_sdk-1.14.0.dist-info}/METADATA +1 -1
- {hatchet_sdk-1.12.3.dist-info → hatchet_sdk-1.14.0.dist-info}/RECORD +73 -83
- hatchet_sdk/v0/contracts/dispatcher_pb2.py +0 -102
- hatchet_sdk/v0/contracts/dispatcher_pb2.pyi +0 -387
- hatchet_sdk/v0/contracts/dispatcher_pb2_grpc.py +0 -621
- hatchet_sdk/v0/contracts/events_pb2.py +0 -46
- hatchet_sdk/v0/contracts/events_pb2.pyi +0 -87
- hatchet_sdk/v0/contracts/events_pb2_grpc.py +0 -274
- hatchet_sdk/v0/contracts/workflows_pb2.py +0 -80
- hatchet_sdk/v0/contracts/workflows_pb2.pyi +0 -312
- hatchet_sdk/v0/contracts/workflows_pb2_grpc.py +0 -277
- hatchet_sdk/v0/logger.py +0 -13
- {hatchet_sdk-1.12.3.dist-info → hatchet_sdk-1.14.0.dist-info}/WHEEL +0 -0
- {hatchet_sdk-1.12.3.dist-info → hatchet_sdk-1.14.0.dist-info}/entry_points.txt +0 -0
hatchet_sdk/v0/v2/callable.py
CHANGED
|
@@ -11,9 +11,7 @@ from typing import (
|
|
|
11
11
|
Union,
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
from hatchet_sdk.
|
|
15
|
-
from hatchet_sdk.v0.context.context import Context
|
|
16
|
-
from hatchet_sdk.v0.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
14
|
+
from hatchet_sdk.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
17
15
|
CreateStepRateLimit,
|
|
18
16
|
CreateWorkflowJobOpts,
|
|
19
17
|
CreateWorkflowStepOpts,
|
|
@@ -23,8 +21,10 @@ from hatchet_sdk.v0.contracts.workflows_pb2 import ( # type: ignore[attr-define
|
|
|
23
21
|
WorkflowConcurrencyOpts,
|
|
24
22
|
WorkflowKind,
|
|
25
23
|
)
|
|
24
|
+
from hatchet_sdk.logger import logger
|
|
25
|
+
from hatchet_sdk.v0.clients.admin import ChildTriggerWorkflowOptions
|
|
26
|
+
from hatchet_sdk.v0.context.context import Context
|
|
26
27
|
from hatchet_sdk.v0.labels import DesiredWorkerLabel
|
|
27
|
-
from hatchet_sdk.v0.logger import logger
|
|
28
28
|
from hatchet_sdk.v0.rate_limit import RateLimit
|
|
29
29
|
from hatchet_sdk.v0.v2.concurrency import ConcurrencyFunction
|
|
30
30
|
from hatchet_sdk.v0.workflow_run import RunRef
|
hatchet_sdk/v0/v2/concurrency.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from typing import Any, Callable
|
|
2
2
|
|
|
3
|
-
from hatchet_sdk.
|
|
4
|
-
from hatchet_sdk.v0.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
3
|
+
from hatchet_sdk.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
5
4
|
ConcurrencyLimitStrategy,
|
|
6
5
|
)
|
|
6
|
+
from hatchet_sdk.v0.context.context import Context
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ConcurrencyFunction:
|
hatchet_sdk/v0/v2/hatchet.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from typing import Any, Callable, TypeVar, Union
|
|
2
2
|
|
|
3
|
-
from hatchet_sdk.
|
|
4
|
-
from hatchet_sdk.v0.context.context import Context
|
|
5
|
-
from hatchet_sdk.v0.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
3
|
+
from hatchet_sdk.contracts.workflows_pb2 import ( # type: ignore[attr-defined]
|
|
6
4
|
ConcurrencyLimitStrategy,
|
|
7
5
|
StickyStrategy,
|
|
8
6
|
)
|
|
7
|
+
from hatchet_sdk.v0 import Worker
|
|
8
|
+
from hatchet_sdk.v0.context.context import Context
|
|
9
9
|
from hatchet_sdk.v0.hatchet import Hatchet as HatchetV1
|
|
10
10
|
from hatchet_sdk.v0.hatchet import workflow
|
|
11
11
|
from hatchet_sdk.v0.labels import DesiredWorkerLabel
|
|
@@ -8,6 +8,12 @@ from typing import Any, List, Mapping, Optional
|
|
|
8
8
|
|
|
9
9
|
import grpc
|
|
10
10
|
|
|
11
|
+
from hatchet_sdk.contracts.dispatcher_pb2 import (
|
|
12
|
+
GROUP_KEY_EVENT_TYPE_STARTED,
|
|
13
|
+
STEP_EVENT_TYPE_STARTED,
|
|
14
|
+
ActionType,
|
|
15
|
+
)
|
|
16
|
+
from hatchet_sdk.logger import logger
|
|
11
17
|
from hatchet_sdk.v0.client import Client, new_client_raw
|
|
12
18
|
from hatchet_sdk.v0.clients.dispatcher.action_listener import Action
|
|
13
19
|
from hatchet_sdk.v0.clients.dispatcher.dispatcher import (
|
|
@@ -16,13 +22,7 @@ from hatchet_sdk.v0.clients.dispatcher.dispatcher import (
|
|
|
16
22
|
new_dispatcher,
|
|
17
23
|
)
|
|
18
24
|
from hatchet_sdk.v0.clients.rest.models.update_worker_request import UpdateWorkerRequest
|
|
19
|
-
from hatchet_sdk.v0.contracts.dispatcher_pb2 import (
|
|
20
|
-
GROUP_KEY_EVENT_TYPE_STARTED,
|
|
21
|
-
STEP_EVENT_TYPE_STARTED,
|
|
22
|
-
ActionType,
|
|
23
|
-
)
|
|
24
25
|
from hatchet_sdk.v0.loader import ClientConfig
|
|
25
|
-
from hatchet_sdk.v0.logger import logger
|
|
26
26
|
from hatchet_sdk.v0.utils.backoff import exp_backoff_sleep
|
|
27
27
|
|
|
28
28
|
ACTION_EVENT_RETRY_COUNT = 5
|
|
@@ -4,11 +4,11 @@ from dataclasses import dataclass, field
|
|
|
4
4
|
from multiprocessing import Queue
|
|
5
5
|
from typing import Callable, TypeVar
|
|
6
6
|
|
|
7
|
+
from hatchet_sdk.logger import logger
|
|
7
8
|
from hatchet_sdk.v0 import Context
|
|
8
9
|
from hatchet_sdk.v0.client import Client, new_client_raw
|
|
9
10
|
from hatchet_sdk.v0.clients.dispatcher.action_listener import Action
|
|
10
11
|
from hatchet_sdk.v0.loader import ClientConfig
|
|
11
|
-
from hatchet_sdk.v0.logger import logger
|
|
12
12
|
from hatchet_sdk.v0.utils.types import WorkflowValidator
|
|
13
13
|
from hatchet_sdk.v0.worker.runner.runner import Runner
|
|
14
14
|
from hatchet_sdk.v0.worker.runner.utils.capture_logs import capture_logs
|
|
@@ -13,15 +13,7 @@ from typing import Any, Callable, Dict, cast
|
|
|
13
13
|
|
|
14
14
|
from pydantic import BaseModel
|
|
15
15
|
|
|
16
|
-
from hatchet_sdk.
|
|
17
|
-
from hatchet_sdk.v0.clients.admin import new_admin
|
|
18
|
-
from hatchet_sdk.v0.clients.dispatcher.action_listener import Action
|
|
19
|
-
from hatchet_sdk.v0.clients.dispatcher.dispatcher import new_dispatcher
|
|
20
|
-
from hatchet_sdk.v0.clients.run_event_listener import new_listener
|
|
21
|
-
from hatchet_sdk.v0.clients.workflow_listener import PooledWorkflowRunListener
|
|
22
|
-
from hatchet_sdk.v0.context import Context # type: ignore[attr-defined]
|
|
23
|
-
from hatchet_sdk.v0.context.worker_context import WorkerContext
|
|
24
|
-
from hatchet_sdk.v0.contracts.dispatcher_pb2 import (
|
|
16
|
+
from hatchet_sdk.contracts.dispatcher_pb2 import (
|
|
25
17
|
GROUP_KEY_EVENT_TYPE_COMPLETED,
|
|
26
18
|
GROUP_KEY_EVENT_TYPE_FAILED,
|
|
27
19
|
GROUP_KEY_EVENT_TYPE_STARTED,
|
|
@@ -30,8 +22,16 @@ from hatchet_sdk.v0.contracts.dispatcher_pb2 import (
|
|
|
30
22
|
STEP_EVENT_TYPE_STARTED,
|
|
31
23
|
ActionType,
|
|
32
24
|
)
|
|
25
|
+
from hatchet_sdk.logger import logger
|
|
26
|
+
from hatchet_sdk.v0.client import new_client_raw
|
|
27
|
+
from hatchet_sdk.v0.clients.admin import new_admin
|
|
28
|
+
from hatchet_sdk.v0.clients.dispatcher.action_listener import Action
|
|
29
|
+
from hatchet_sdk.v0.clients.dispatcher.dispatcher import new_dispatcher
|
|
30
|
+
from hatchet_sdk.v0.clients.run_event_listener import new_listener
|
|
31
|
+
from hatchet_sdk.v0.clients.workflow_listener import PooledWorkflowRunListener
|
|
32
|
+
from hatchet_sdk.v0.context import Context # type: ignore[attr-defined]
|
|
33
|
+
from hatchet_sdk.v0.context.worker_context import WorkerContext
|
|
33
34
|
from hatchet_sdk.v0.loader import ClientConfig
|
|
34
|
-
from hatchet_sdk.v0.logger import logger
|
|
35
35
|
from hatchet_sdk.v0.utils.types import WorkflowValidator
|
|
36
36
|
from hatchet_sdk.v0.v2.callable import DurableContext
|
|
37
37
|
from hatchet_sdk.v0.worker.action_listener_process import ActionEvent
|
|
@@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
5
5
|
from io import StringIO
|
|
6
6
|
from typing import Any, Coroutine
|
|
7
7
|
|
|
8
|
-
from hatchet_sdk
|
|
8
|
+
from hatchet_sdk import logger
|
|
9
9
|
from hatchet_sdk.v0.clients.events import EventClient
|
|
10
10
|
|
|
11
11
|
wr: contextvars.ContextVar[str | None] = contextvars.ContextVar(
|
hatchet_sdk/v0/worker/worker.py
CHANGED
|
@@ -17,11 +17,11 @@ from aiohttp.web_request import Request
|
|
|
17
17
|
from aiohttp.web_response import Response
|
|
18
18
|
from prometheus_client import CONTENT_TYPE_LATEST, Gauge, generate_latest
|
|
19
19
|
|
|
20
|
+
from hatchet_sdk.contracts.workflows_pb2 import CreateWorkflowVersionOpts
|
|
21
|
+
from hatchet_sdk.logger import logger
|
|
20
22
|
from hatchet_sdk.v0 import Context
|
|
21
23
|
from hatchet_sdk.v0.client import Client, new_client_raw
|
|
22
|
-
from hatchet_sdk.v0.contracts.workflows_pb2 import CreateWorkflowVersionOpts
|
|
23
24
|
from hatchet_sdk.v0.loader import ClientConfig
|
|
24
|
-
from hatchet_sdk.v0.logger import logger
|
|
25
25
|
from hatchet_sdk.v0.utils.types import WorkflowValidator
|
|
26
26
|
from hatchet_sdk.v0.utils.typing import is_basemodel_subclass
|
|
27
27
|
from hatchet_sdk.v0.v2.callable import HatchetCallable
|
hatchet_sdk/v0/workflow.py
CHANGED
|
@@ -13,8 +13,7 @@ from typing import (
|
|
|
13
13
|
|
|
14
14
|
from pydantic import BaseModel
|
|
15
15
|
|
|
16
|
-
from hatchet_sdk.
|
|
17
|
-
from hatchet_sdk.v0.contracts.workflows_pb2 import (
|
|
16
|
+
from hatchet_sdk.contracts.workflows_pb2 import (
|
|
18
17
|
CreateWorkflowJobOpts,
|
|
19
18
|
CreateWorkflowStepOpts,
|
|
20
19
|
CreateWorkflowVersionOpts,
|
|
@@ -22,7 +21,8 @@ from hatchet_sdk.v0.contracts.workflows_pb2 import (
|
|
|
22
21
|
WorkflowConcurrencyOpts,
|
|
23
22
|
WorkflowKind,
|
|
24
23
|
)
|
|
25
|
-
from hatchet_sdk.
|
|
24
|
+
from hatchet_sdk.logger import logger
|
|
25
|
+
from hatchet_sdk.v0 import ConcurrencyLimitStrategy
|
|
26
26
|
from hatchet_sdk.v0.utils.typing import is_basemodel_subclass
|
|
27
27
|
|
|
28
28
|
|
hatchet_sdk/waits.py
CHANGED
|
@@ -6,6 +6,7 @@ from uuid import uuid4
|
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel, Field
|
|
8
8
|
|
|
9
|
+
from hatchet_sdk.config import ClientConfig
|
|
9
10
|
from hatchet_sdk.contracts.v1.shared.condition_pb2 import Action as ProtoAction
|
|
10
11
|
from hatchet_sdk.contracts.v1.shared.condition_pb2 import (
|
|
11
12
|
BaseMatchCondition,
|
|
@@ -53,7 +54,7 @@ class Condition(ABC):
|
|
|
53
54
|
|
|
54
55
|
@abstractmethod
|
|
55
56
|
def to_proto(
|
|
56
|
-
self,
|
|
57
|
+
self, config: ClientConfig
|
|
57
58
|
) -> UserEventMatchCondition | ParentOverrideMatchCondition | SleepMatchCondition:
|
|
58
59
|
pass
|
|
59
60
|
|
|
@@ -71,7 +72,7 @@ class SleepCondition(Condition):
|
|
|
71
72
|
|
|
72
73
|
self.duration = duration
|
|
73
74
|
|
|
74
|
-
def to_proto(self) -> SleepMatchCondition:
|
|
75
|
+
def to_proto(self, config: ClientConfig) -> SleepMatchCondition:
|
|
75
76
|
return SleepMatchCondition(
|
|
76
77
|
base=self.base.to_proto(),
|
|
77
78
|
sleep_for=timedelta_to_expr(self.duration),
|
|
@@ -95,10 +96,10 @@ class UserEventCondition(Condition):
|
|
|
95
96
|
self.event_key = event_key
|
|
96
97
|
self.expression = expression
|
|
97
98
|
|
|
98
|
-
def to_proto(self) -> UserEventMatchCondition:
|
|
99
|
+
def to_proto(self, config: ClientConfig) -> UserEventMatchCondition:
|
|
99
100
|
return UserEventMatchCondition(
|
|
100
101
|
base=self.base.to_proto(),
|
|
101
|
-
user_event_key=self.event_key,
|
|
102
|
+
user_event_key=config.apply_namespace(self.event_key),
|
|
102
103
|
)
|
|
103
104
|
|
|
104
105
|
|
|
@@ -124,7 +125,7 @@ class ParentCondition(Condition):
|
|
|
124
125
|
|
|
125
126
|
self.parent = parent
|
|
126
127
|
|
|
127
|
-
def to_proto(self) -> ParentOverrideMatchCondition:
|
|
128
|
+
def to_proto(self, config: ClientConfig) -> ParentOverrideMatchCondition:
|
|
128
129
|
return ParentOverrideMatchCondition(
|
|
129
130
|
base=self.base.to_proto(),
|
|
130
131
|
parent_readable_id=self.parent.name,
|
|
@@ -4,9 +4,10 @@ import signal
|
|
|
4
4
|
import time
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from multiprocessing import Queue
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import grpc
|
|
10
|
+
from grpc.aio import UnaryUnaryCall
|
|
10
11
|
|
|
11
12
|
from hatchet_sdk.client import Client
|
|
12
13
|
from hatchet_sdk.clients.dispatcher.action_listener import (
|
|
@@ -19,6 +20,9 @@ from hatchet_sdk.config import ClientConfig
|
|
|
19
20
|
from hatchet_sdk.contracts.dispatcher_pb2 import (
|
|
20
21
|
GROUP_KEY_EVENT_TYPE_STARTED,
|
|
21
22
|
STEP_EVENT_TYPE_STARTED,
|
|
23
|
+
ActionEventResponse,
|
|
24
|
+
GroupKeyActionEvent,
|
|
25
|
+
StepActionEvent,
|
|
22
26
|
)
|
|
23
27
|
from hatchet_sdk.logger import logger
|
|
24
28
|
from hatchet_sdk.runnables.action import Action, ActionType
|
|
@@ -29,6 +33,7 @@ from hatchet_sdk.runnables.contextvars import (
|
|
|
29
33
|
ctx_workflow_run_id,
|
|
30
34
|
)
|
|
31
35
|
from hatchet_sdk.utils.backoff import exp_backoff_sleep
|
|
36
|
+
from hatchet_sdk.utils.typing import STOP_LOOP, STOP_LOOP_TYPE
|
|
32
37
|
|
|
33
38
|
ACTION_EVENT_RETRY_COUNT = 5
|
|
34
39
|
|
|
@@ -41,9 +46,6 @@ class ActionEvent:
|
|
|
41
46
|
should_not_retry: bool
|
|
42
47
|
|
|
43
48
|
|
|
44
|
-
STOP_LOOP_TYPE = Literal["STOP_LOOP"]
|
|
45
|
-
STOP_LOOP: STOP_LOOP_TYPE = "STOP_LOOP" # Sentinel object to stop the loop
|
|
46
|
-
|
|
47
49
|
BLOCKED_THREAD_WARNING = "THE TIME TO START THE TASK RUN IS TOO LONG, THE EVENT LOOP MAY BE BLOCKED. See https://docs.hatchet.run/blog/warning-event-loop-blocked for details and debugging help."
|
|
48
50
|
|
|
49
51
|
|
|
@@ -56,9 +58,9 @@ class WorkerActionListenerProcess:
|
|
|
56
58
|
config: ClientConfig,
|
|
57
59
|
action_queue: "Queue[Action]",
|
|
58
60
|
event_queue: "Queue[ActionEvent | STOP_LOOP_TYPE]",
|
|
59
|
-
handle_kill: bool
|
|
60
|
-
debug: bool
|
|
61
|
-
labels: dict[str, str | int]
|
|
61
|
+
handle_kill: bool,
|
|
62
|
+
debug: bool,
|
|
63
|
+
labels: dict[str, str | int],
|
|
62
64
|
) -> None:
|
|
63
65
|
self.name = name
|
|
64
66
|
self.actions = actions
|
|
@@ -75,6 +77,14 @@ class WorkerActionListenerProcess:
|
|
|
75
77
|
self.action_loop_task: asyncio.Task[None] | None = None
|
|
76
78
|
self.event_send_loop_task: asyncio.Task[None] | None = None
|
|
77
79
|
self.running_step_runs: dict[str, float] = {}
|
|
80
|
+
self.step_action_events: set[
|
|
81
|
+
asyncio.Task[UnaryUnaryCall[StepActionEvent, ActionEventResponse] | None]
|
|
82
|
+
] = set()
|
|
83
|
+
self.group_key_action_events: set[
|
|
84
|
+
asyncio.Task[
|
|
85
|
+
UnaryUnaryCall[GroupKeyActionEvent, ActionEventResponse] | None
|
|
86
|
+
]
|
|
87
|
+
] = set()
|
|
78
88
|
|
|
79
89
|
if self.debug:
|
|
80
90
|
logger.setLevel(logging.DEBUG)
|
|
@@ -144,20 +154,21 @@ class WorkerActionListenerProcess:
|
|
|
144
154
|
break
|
|
145
155
|
|
|
146
156
|
logger.debug(f"tx: event: {event.action.action_id}/{event.type}")
|
|
147
|
-
asyncio.create_task(self.send_event(event))
|
|
157
|
+
t = asyncio.create_task(self.send_event(event))
|
|
158
|
+
self.step_action_events.add(t)
|
|
159
|
+
t.add_done_callback(lambda t: self.step_action_events.discard(t))
|
|
148
160
|
|
|
149
161
|
async def start_blocked_main_loop(self) -> None:
|
|
150
162
|
threshold = 1
|
|
151
163
|
while not self.killing:
|
|
152
164
|
count = 0
|
|
153
|
-
for
|
|
165
|
+
for start_time in self.running_step_runs.values():
|
|
154
166
|
diff = self.now() - start_time
|
|
155
167
|
if diff > threshold:
|
|
156
168
|
count += 1
|
|
157
169
|
|
|
158
170
|
if count > 0:
|
|
159
171
|
logger.warning(f"{BLOCKED_THREAD_WARNING}: Waiting Steps {count}")
|
|
160
|
-
print(asyncio.current_task())
|
|
161
172
|
await asyncio.sleep(1)
|
|
162
173
|
|
|
163
174
|
async def send_event(self, event: ActionEvent, retry_attempt: int = 1) -> None:
|
|
@@ -187,7 +198,7 @@ class WorkerActionListenerProcess:
|
|
|
187
198
|
self.now()
|
|
188
199
|
)
|
|
189
200
|
|
|
190
|
-
asyncio.create_task(
|
|
201
|
+
send_started_event_task = asyncio.create_task(
|
|
191
202
|
self.dispatcher_client.send_step_action_event(
|
|
192
203
|
event.action,
|
|
193
204
|
event.type,
|
|
@@ -195,14 +206,23 @@ class WorkerActionListenerProcess:
|
|
|
195
206
|
event.should_not_retry,
|
|
196
207
|
)
|
|
197
208
|
)
|
|
209
|
+
|
|
210
|
+
self.step_action_events.add(send_started_event_task)
|
|
211
|
+
send_started_event_task.add_done_callback(
|
|
212
|
+
lambda t: self.step_action_events.discard(t)
|
|
213
|
+
)
|
|
198
214
|
case ActionType.CANCEL_STEP_RUN:
|
|
199
215
|
logger.debug("unimplemented event send")
|
|
200
216
|
case ActionType.START_GET_GROUP_KEY:
|
|
201
|
-
asyncio.create_task(
|
|
217
|
+
get_group_key_task = asyncio.create_task(
|
|
202
218
|
self.dispatcher_client.send_group_key_action_event(
|
|
203
219
|
event.action, event.type, event.payload
|
|
204
220
|
)
|
|
205
221
|
)
|
|
222
|
+
self.group_key_action_events.add(get_group_key_task)
|
|
223
|
+
get_group_key_task.add_done_callback(
|
|
224
|
+
lambda t: self.group_key_action_events.discard(t)
|
|
225
|
+
)
|
|
206
226
|
case _:
|
|
207
227
|
logger.error("unknown action type for event send")
|
|
208
228
|
except Exception as e:
|
|
@@ -317,7 +337,7 @@ def worker_action_listener_process(*args: Any, **kwargs: Any) -> None:
|
|
|
317
337
|
process = WorkerActionListenerProcess(*args, **kwargs)
|
|
318
338
|
await process.start()
|
|
319
339
|
# Keep the process running
|
|
320
|
-
while not process.killing:
|
|
340
|
+
while not process.killing: # noqa: ASYNC110
|
|
321
341
|
await asyncio.sleep(0.1)
|
|
322
342
|
|
|
323
343
|
asyncio.run(run())
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import logging
|
|
3
3
|
from multiprocessing import Queue
|
|
4
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, TypeVar
|
|
5
5
|
|
|
6
6
|
from hatchet_sdk.client import Client
|
|
7
7
|
from hatchet_sdk.config import ClientConfig
|
|
8
8
|
from hatchet_sdk.logger import logger
|
|
9
9
|
from hatchet_sdk.runnables.action import Action
|
|
10
10
|
from hatchet_sdk.runnables.task import Task
|
|
11
|
+
from hatchet_sdk.utils.typing import STOP_LOOP, STOP_LOOP_TYPE
|
|
11
12
|
from hatchet_sdk.worker.action_listener_process import ActionEvent
|
|
12
13
|
from hatchet_sdk.worker.runner.runner import Runner
|
|
13
|
-
from hatchet_sdk.worker.runner.utils.capture_logs import capture_logs
|
|
14
|
-
|
|
15
|
-
STOP_LOOP_TYPE = Literal["STOP_LOOP"]
|
|
16
|
-
STOP_LOOP: STOP_LOOP_TYPE = "STOP_LOOP"
|
|
14
|
+
from hatchet_sdk.worker.runner.utils.capture_logs import AsyncLogSender, capture_logs
|
|
17
15
|
|
|
18
16
|
T = TypeVar("T")
|
|
19
17
|
|
|
@@ -28,10 +26,10 @@ class WorkerActionRunLoopManager:
|
|
|
28
26
|
action_queue: "Queue[Action | STOP_LOOP_TYPE]",
|
|
29
27
|
event_queue: "Queue[ActionEvent]",
|
|
30
28
|
loop: asyncio.AbstractEventLoop,
|
|
31
|
-
handle_kill: bool
|
|
32
|
-
debug: bool
|
|
33
|
-
labels: dict[str, str | int]
|
|
34
|
-
lifespan_context: Any | None
|
|
29
|
+
handle_kill: bool,
|
|
30
|
+
debug: bool,
|
|
31
|
+
labels: dict[str, str | int] | None,
|
|
32
|
+
lifespan_context: Any | None,
|
|
35
33
|
) -> None:
|
|
36
34
|
self.name = name
|
|
37
35
|
self.action_registry = action_registry
|
|
@@ -52,15 +50,19 @@ class WorkerActionRunLoopManager:
|
|
|
52
50
|
self.runner: Runner | None = None
|
|
53
51
|
|
|
54
52
|
self.client = Client(config=self.config, debug=self.debug)
|
|
53
|
+
self.start_loop_manager_task: asyncio.Task[None] | None = None
|
|
54
|
+
self.log_sender = AsyncLogSender(self.client.event)
|
|
55
|
+
self.log_task = self.loop.create_task(self.log_sender.consume())
|
|
56
|
+
|
|
55
57
|
self.start()
|
|
56
58
|
|
|
57
59
|
def start(self) -> None:
|
|
58
|
-
|
|
60
|
+
self.start_loop_manager_task = self.loop.create_task(self.aio_start())
|
|
59
61
|
|
|
60
62
|
async def aio_start(self, retry_count: int = 1) -> None:
|
|
61
63
|
await capture_logs(
|
|
62
64
|
self.client.log_interceptor,
|
|
63
|
-
self.
|
|
65
|
+
self.log_sender,
|
|
64
66
|
self._async_start,
|
|
65
67
|
)()
|
|
66
68
|
|
|
@@ -75,6 +77,7 @@ class WorkerActionRunLoopManager:
|
|
|
75
77
|
self.killing = True
|
|
76
78
|
|
|
77
79
|
self.action_queue.put(STOP_LOOP)
|
|
80
|
+
self.log_sender.publish(STOP_LOOP)
|
|
78
81
|
|
|
79
82
|
async def wait_for_tasks(self) -> None:
|
|
80
83
|
if self.runner:
|
|
@@ -89,6 +92,7 @@ class WorkerActionRunLoopManager:
|
|
|
89
92
|
self.action_registry,
|
|
90
93
|
self.labels,
|
|
91
94
|
self.lifespan_context,
|
|
95
|
+
self.log_sender,
|
|
92
96
|
)
|
|
93
97
|
|
|
94
98
|
logger.debug(f"'{self.name}' waiting for {list(self.action_registry.keys())}")
|