@@ -17,11 +17,26 @@ class Worker
17
17
# finished) and will raise if any of the workers raises a fatal error.
18
18
#
19
19
# @param workers [Array<Temporalio::Worker>] A list of the workers to be run.
20
+ # @param shutdown_signals [Array<String>] A list of process signals for the worker to stop on.
21
+ # This argument can not be used with a custom block.
20
22
#
21
23
# @yield Optionally you can provide a block by the end of which all the workers will be shut
22
24
# down. Any errors raised from this block will be re-raised by this method.
23
- def self . run ( *workers , &block )
24
- # TODO: Add signal handling
25
+ def self . run ( *workers , shutdown_signals : [ ] , &block )
26
+ unless shutdown_signals . empty?
27
+ if block
28
+ raise ArgumentError , 'Temporalio::Worker.run accepts :shutdown_signals or a block, but not both'
29
+ end
30
+
31
+ signal_queue = Queue . new
32
+
33
+ shutdown_signals . each do |signal |
34
+ Signal . trap ( signal ) { signal_queue . close }
35
+ end
36
+
37
+ block = -> { signal_queue . pop }
38
+ end
39
+
25
40
Runner . new ( *workers ) . run ( &block )
26
41
end
27
42
@@ -36,6 +51,9 @@ def self.run(*workers, &block)
36
51
# @param activity_executor [ThreadPoolExecutor] Concurrent executor for all activities. Defaults
37
52
# to a {ThreadPoolExecutor} with `:max_concurrent_activities` available threads.
38
53
# @param max_concurrent_activities [Integer] Number of concurrently running activities.
54
+ # @param graceful_shutdown_timeout [Integer] Amount of time (in seconds) activities are given
55
+ # after a shutdown to complete before they are cancelled. A default value of `nil` means that
56
+ # activities are never cancelled when handling a shutdown.
39
57
#
40
58
# @raise [ArgumentError] When no activities or workflows have been provided.
41
59
def initialize (
@@ -45,7 +63,8 @@ def initialize(
45
63
activities : [ ] ,
46
64
data_converter : Temporalio ::DataConverter . new ,
47
65
activity_executor : nil ,
48
- max_concurrent_activities : 100
66
+ max_concurrent_activities : 100 ,
67
+ graceful_shutdown_timeout : nil
49
68
)
50
69
# TODO: Add worker interceptors
51
70
@started = false
@@ -59,13 +78,17 @@ def initialize(
59
78
namespace ,
60
79
task_queue ,
61
80
)
62
- @activity_worker = init_activity_worker (
63
- task_queue ,
64
- @core_worker ,
65
- activities ,
66
- data_converter ,
67
- @activity_executor ,
68
- )
81
+ @activity_worker =
82
+ unless activities . empty?
83
+ Worker ::ActivityWorker . new (
84
+ task_queue ,
85
+ @core_worker ,
86
+ activities ,
87
+ data_converter ,
88
+ @activity_executor ,
89
+ graceful_shutdown_timeout ,
90
+ )
91
+ end
69
92
@workflow_worker = nil
70
93
71
94
if !@activity_worker && !@workflow_worker
@@ -171,11 +194,5 @@ def running?
171
194
172
195
attr_reader :mutex , :runtime , :activity_executor , :core_worker , :activity_worker ,
173
196
:workflow_worker , :runner
174
-
175
- def init_activity_worker ( task_queue , core_worker , activities , data_converter , executor )
176
- return if activities . empty?
177
-
178
- Worker ::ActivityWorker . new ( task_queue , core_worker , activities , data_converter , executor )
179
- end
180
197
end
181
198
end
0 commit comments