1313from pyzeebe .task import task_builder
1414from pyzeebe .task .exception_handler import ExceptionHandler
1515from pyzeebe .worker .job_executor import JobExecutor
16- from pyzeebe .worker .job_poller import JobPoller
16+ from pyzeebe .worker .job_poller import JobPoller , JobStreamer
1717from pyzeebe .worker .task_router import ZeebeTaskRouter
1818from pyzeebe .worker .task_state import TaskState
1919
@@ -34,6 +34,8 @@ def __init__(
3434 poll_retry_delay : int = 5 ,
3535 tenant_ids : list [str ] | None = None ,
3636 exception_handler : ExceptionHandler | None = None ,
37+ stream_enabled : bool = False ,
38+ stream_request_timeout : int = 3600 ,
3739 ):
3840 """
3941 Args:
@@ -46,6 +48,9 @@ def __init__(
4648 max_connection_retries (int): Amount of connection retries before worker gives up on connecting to zeebe. To setup with infinite retries use -1
4749 poll_retry_delay (int): The number of seconds to wait before attempting to poll again when reaching max amount of running jobs
4850 tenant_ids (list[str]): A list of tenant IDs for which to activate jobs. New in Zeebe 8.3.
51+ stream_enabled (bool): Enables the job worker to stream jobs. It will still poll for older jobs, but streaming is favored. New in Zeebe 8.4.
52+ stream_request_timeout (int): If streaming is enabled, this sets the timeout on the underlying job stream.
53+ It's useful to set a few hours to load-balance your streams over time. New in Zeebe 8.4.
4954 """
5055 super ().__init__ (before , after , exception_handler )
5156 self .zeebe_adapter = ZeebeAdapter (grpc_channel , max_connection_retries )
@@ -54,31 +59,46 @@ def __init__(
5459 self .poll_retry_delay = poll_retry_delay
5560 self .tenant_ids = tenant_ids
5661 self ._job_pollers : list [JobPoller ] = []
62+ self ._job_streamers : list [JobStreamer ] = []
5763 self ._job_executors : list [JobExecutor ] = []
5864 self ._stop_event = anyio .Event ()
65+ self ._stream_enabled = stream_enabled
66+ self ._stream_request_timeout = stream_request_timeout
5967
6068 def _init_tasks (self ) -> None :
61- self ._job_executors , self ._job_pollers = [], []
69+ self ._job_executors , self ._job_pollers , self . _job_streamers = [], [], []
6270
6371 for task in self .tasks :
6472 jobs_queue = asyncio .Queue [Job ]()
6573 task_state = TaskState ()
6674
6775 poller = JobPoller (
68- self .zeebe_adapter ,
69- task ,
70- jobs_queue ,
71- self .name ,
72- self .request_timeout ,
73- task_state ,
74- self .poll_retry_delay ,
75- self .tenant_ids ,
76+ zeebe_adapter = self .zeebe_adapter ,
77+ task = task ,
78+ queue = jobs_queue ,
79+ worker_name = self .name ,
80+ request_timeout = self .request_timeout ,
81+ task_state = task_state ,
82+ poll_retry_delay = self .poll_retry_delay ,
83+ tenant_ids = self .tenant_ids ,
7684 )
7785 executor = JobExecutor (task , jobs_queue , task_state , self .zeebe_adapter )
7886
7987 self ._job_pollers .append (poller )
8088 self ._job_executors .append (executor )
8189
90+ if self ._stream_enabled :
91+ streamer = JobStreamer (
92+ zeebe_adapter = self .zeebe_adapter ,
93+ task = task ,
94+ queue = jobs_queue ,
95+ worker_name = self .name ,
96+ stream_request_timeout = self ._stream_request_timeout ,
97+ task_state = task_state ,
98+ tenant_ids = self .tenant_ids ,
99+ )
100+ self ._job_streamers .append (streamer )
101+
82102 async def work (self ) -> None :
83103 """
84104 Start the worker. The worker will poll zeebe for jobs of each task in a different asyncio task.
@@ -97,6 +117,9 @@ async def work(self) -> None:
97117 for poller in self ._job_pollers :
98118 tg .start_soon (poller .poll )
99119
120+ for streamer in self ._job_streamers :
121+ tg .start_soon (streamer .poll )
122+
100123 for executor in self ._job_executors :
101124 tg .start_soon (executor .execute )
102125
@@ -113,6 +136,9 @@ async def stop(self) -> None:
113136 for poller in self ._job_pollers :
114137 await poller .stop ()
115138
139+ for streamer in self ._job_streamers :
140+ await streamer .stop ()
141+
116142 for executor in self ._job_executors :
117143 await executor .stop ()
118144
0 commit comments