1818 Optional ,
1919 Sequence ,
2020 Type ,
21+ Union ,
2122 cast ,
2223)
2324
24- from typing_extensions import TypedDict
25+ from typing_extensions import TypeAlias , TypedDict
2526
2627import temporalio .activity
2728import temporalio .api .common .v1
4849logger = logging .getLogger (__name__ )
4950
5051
52+ @dataclass (frozen = True )
53+ class PollerBehaviorSimpleMaximum :
54+ """A poller behavior that will attempt to poll as long as a slot is available, up to the
55+ provided maximum. Cannot be less than two for workflow tasks, or one for other tasks.
56+ """
57+
58+ maximum : int = 5
59+
60+ def _to_bridge (self ) -> temporalio .bridge .worker .PollerBehavior :
61+ return temporalio .bridge .worker .PollerBehaviorSimpleMaximum (
62+ simple_maximum = self .maximum
63+ )
64+
65+
66+ @dataclass (frozen = True )
67+ class PollerBehaviorAutoscaling :
68+ """A poller behavior that will automatically scale the number of pollers based on feedback
69+ from the server. A slot must be available before beginning polling.
70+ """
71+
72+ minimum : int = 1
73+ """At least this many poll calls will always be attempted (assuming slots are available)."""
74+ maximum : int = 100
75+ """At most this many poll calls will ever be open at once. Must be >= `minimum`."""
76+ initial : int = 5
77+ """This many polls will be attempted initially before scaling kicks in. Must be between
78+ `minimum` and `maximum`."""
79+
80+ def _to_bridge (self ) -> temporalio .bridge .worker .PollerBehavior :
81+ return temporalio .bridge .worker .PollerBehaviorAutoscaling (
82+ minimum = self .minimum ,
83+ maximum = self .maximum ,
84+ initial = self .initial ,
85+ )
86+
87+
88+ PollerBehavior : TypeAlias = Union [
89+ PollerBehaviorSimpleMaximum ,
90+ PollerBehaviorAutoscaling ,
91+ ]
92+
93+
5194class Worker :
5295 """Worker to process workflows and/or activities.
5396
@@ -76,9 +119,9 @@ def __init__(
76119 max_concurrent_activities : Optional [int ] = None ,
77120 max_concurrent_local_activities : Optional [int ] = None ,
78121 tuner : Optional [WorkerTuner ] = None ,
79- max_concurrent_workflow_task_polls : int = 5 ,
122+ max_concurrent_workflow_task_polls : Optional [ int ] = None ,
80123 nonsticky_to_sticky_poll_ratio : float = 0.2 ,
81- max_concurrent_activity_task_polls : int = 5 ,
124+ max_concurrent_activity_task_polls : Optional [ int ] = None ,
82125 no_remote_activities : bool = False ,
83126 sticky_queue_schedule_to_start_timeout : timedelta = timedelta (seconds = 10 ),
84127 max_heartbeat_throttle_interval : timedelta = timedelta (seconds = 60 ),
@@ -94,6 +137,12 @@ def __init__(
94137 use_worker_versioning : bool = False ,
95138 disable_safe_workflow_eviction : bool = False ,
96139 deployment_config : Optional [WorkerDeploymentConfig ] = None ,
140+ workflow_task_poller_behavior : PollerBehavior = PollerBehaviorSimpleMaximum (
141+ maximum = 5
142+ ),
143+ activity_task_poller_behavior : PollerBehavior = PollerBehaviorSimpleMaximum (
144+ maximum = 5
145+ ),
97146 ) -> None :
98147 """Create a worker to process workflows and/or activities.
99148
@@ -152,10 +201,17 @@ def __init__(
152201 ``max_concurrent_workflow_tasks``, ``max_concurrent_activities``, and
153202 ``max_concurrent_local_activities`` arguments.
154203
204+ Defaults to fixed-size 100 slots for each slot kind if unset and none of the
205+ max_* arguments are provided.
206+
155207 WARNING: This argument is experimental
156208 max_concurrent_workflow_task_polls: Maximum number of concurrent
157209 poll workflow task requests we will perform at a time on this
158210 worker's task queue.
211+
212+ If set, will override any value passed to ``workflow_task_poller_behavior``.
213+
214+ WARNING: Deprecated, use ``workflow_task_poller_behavior`` instead
159215 nonsticky_to_sticky_poll_ratio: max_concurrent_workflow_task_polls *
160216 this number = the number of max pollers that will be allowed for
161217 the nonsticky queue when sticky tasks are enabled. If both
@@ -166,6 +222,10 @@ def __init__(
166222 max_concurrent_activity_task_polls: Maximum number of concurrent
167223 poll activity task requests we will perform at a time on this
168224 worker's task queue.
225+
226+ If set, will override any value passed to ``activity_task_poller_behavior``.
227+
228+ WARNING: Deprecated, use ``activity_task_poller_behavior`` instead
169229 no_remote_activities: If true, this worker will only handle workflow
170230 tasks and local activities, it will not poll for activity tasks.
171231 sticky_queue_schedule_to_start_timeout: How long a workflow task is
@@ -231,6 +291,10 @@ def __init__(
231291 deployment_config: Deployment config for the worker. Exclusive with `build_id` and
232292 `use_worker_versioning`.
233293 WARNING: This is an experimental feature and may change in the future.
294+ workflow_task_poller_behavior: Specify the behavior of workflow task polling.
295+ Defaults to a 5-poller maximum.
296+ activity_task_poller_behavior: Specify the behavior of activity task polling.
297+ Defaults to a 5-poller maximum.
234298 """
235299 if not activities and not workflows :
236300 raise ValueError ("At least one activity or workflow must be specified" )
@@ -393,6 +457,15 @@ def __init__(
393457 build_id = build_id
394458 )
395459
460+ if max_concurrent_workflow_task_polls :
461+ workflow_task_poller_behavior = PollerBehaviorSimpleMaximum (
462+ maximum = max_concurrent_workflow_task_polls
463+ )
464+ if max_concurrent_activity_task_polls :
465+ activity_task_poller_behavior = PollerBehaviorSimpleMaximum (
466+ maximum = max_concurrent_activity_task_polls
467+ )
468+
396469 # Create bridge worker last. We have empirically observed that if it is
397470 # created before an error is raised from the activity worker
398471 # constructor, a deadlock/hang will occur presumably while trying to
@@ -408,9 +481,7 @@ def __init__(
408481 identity_override = identity ,
409482 max_cached_workflows = max_cached_workflows ,
410483 tuner = bridge_tuner ,
411- max_concurrent_workflow_task_polls = max_concurrent_workflow_task_polls ,
412484 nonsticky_to_sticky_poll_ratio = nonsticky_to_sticky_poll_ratio ,
413- max_concurrent_activity_task_polls = max_concurrent_activity_task_polls ,
414485 # We have to disable remote activities if a user asks _or_ if we
415486 # are not running an activity worker at all. Otherwise shutdown
416487 # will not proceed properly.
@@ -440,6 +511,8 @@ def __init__(
440511 else set ()
441512 ),
442513 versioning_strategy = versioning_strategy ,
514+ workflow_task_poller_behavior = workflow_task_poller_behavior ._to_bridge (),
515+ activity_task_poller_behavior = activity_task_poller_behavior ._to_bridge (),
443516 ),
444517 )
445518
@@ -696,9 +769,9 @@ class WorkerConfig(TypedDict, total=False):
696769 max_concurrent_activities : Optional [int ]
697770 max_concurrent_local_activities : Optional [int ]
698771 tuner : Optional [WorkerTuner ]
699- max_concurrent_workflow_task_polls : int
772+ max_concurrent_workflow_task_polls : Optional [ int ]
700773 nonsticky_to_sticky_poll_ratio : float
701- max_concurrent_activity_task_polls : int
774+ max_concurrent_activity_task_polls : Optional [ int ]
702775 no_remote_activities : bool
703776 sticky_queue_schedule_to_start_timeout : timedelta
704777 max_heartbeat_throttle_interval : timedelta
@@ -714,6 +787,8 @@ class WorkerConfig(TypedDict, total=False):
714787 use_worker_versioning : bool
715788 disable_safe_workflow_eviction : bool
716789 deployment_config : Optional [WorkerDeploymentConfig ]
790+ workflow_task_poller_behavior : PollerBehavior
791+ activity_task_poller_behavior : PollerBehavior
717792
718793
719794@dataclass
0 commit comments