Skip to content

Commit b5efd2c

Browse files
Add workflow start delay option (#294)
1 parent f41efb7 commit b5efd2c

File tree

6 files changed

+46
-22
lines changed

6 files changed

+46
-22
lines changed

lib/temporal/client.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def initialize(config)
4141
# @option options [Hash] :timeouts check Temporal::Configuration::DEFAULT_TIMEOUTS
4242
# @option options [Hash] :headers
4343
# @option options [Hash] :search_attributes
44+
# @option options [Integer] :start_delay determines the amount of seconds to wait before initiating a Workflow
4445
#
4546
# @return [String] workflow's run ID
4647
def start_workflow(workflow, *input, options: {}, **args)
@@ -67,6 +68,7 @@ def start_workflow(workflow, *input, options: {}, **args)
6768
headers: config.header_propagator_chain.inject(execution_options.headers),
6869
memo: execution_options.memo,
6970
search_attributes: Workflow::Context::Helpers.process_search_attributes(execution_options.search_attributes),
71+
start_delay: execution_options.start_delay
7072
)
7173
else
7274
raise ArgumentError, 'If signal_input is provided, you must also provide signal_name' if signal_name.nil?
@@ -85,7 +87,8 @@ def start_workflow(workflow, *input, options: {}, **args)
8587
memo: execution_options.memo,
8688
search_attributes: Workflow::Context::Helpers.process_search_attributes(execution_options.search_attributes),
8789
signal_name: signal_name,
88-
signal_input: signal_input
90+
signal_input: signal_input,
91+
start_delay: execution_options.start_delay
8992
)
9093
end
9194

lib/temporal/connection/grpc.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ def start_workflow_execution(
120120
headers: nil,
121121
cron_schedule: nil,
122122
memo: nil,
123-
search_attributes: nil
123+
search_attributes: nil,
124+
start_delay: nil
124125
)
125126
request = Temporalio::Api::WorkflowService::V1::StartWorkflowExecutionRequest.new(
126127
identity: identity,
@@ -137,6 +138,7 @@ def start_workflow_execution(
137138
workflow_execution_timeout: execution_timeout,
138139
workflow_run_timeout: run_timeout,
139140
workflow_task_timeout: task_timeout,
141+
workflow_start_delay: start_delay,
140142
request_id: SecureRandom.uuid,
141143
header: Temporalio::Api::Common::V1::Header.new(
142144
fields: converter.to_payload_map(headers || {})
@@ -379,7 +381,8 @@ def signal_with_start_workflow_execution(
379381
headers: nil,
380382
cron_schedule: nil,
381383
memo: nil,
382-
search_attributes: nil
384+
search_attributes: nil,
385+
start_delay: nil
383386
)
384387
proto_header_fields = if headers.nil?
385388
converter.to_payload_map({})
@@ -406,6 +409,7 @@ def signal_with_start_workflow_execution(
406409
workflow_execution_timeout: execution_timeout,
407410
workflow_run_timeout: run_timeout,
408411
workflow_task_timeout: task_timeout,
412+
workflow_start_delay: start_delay,
409413
request_id: SecureRandom.uuid,
410414
header: Temporalio::Api::Common::V1::Header.new(
411415
fields: proto_header_fields

lib/temporal/execution_options.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
module Temporal
55
class ExecutionOptions
6-
attr_reader :name, :namespace, :task_queue, :retry_policy, :timeouts, :headers, :memo, :search_attributes
6+
attr_reader :name, :namespace, :task_queue, :retry_policy, :timeouts, :headers, :memo, :search_attributes,
7+
:start_delay
78

89
def initialize(object, options, defaults = nil)
910
# Options are treated as overrides and take precedence
@@ -15,6 +16,7 @@ def initialize(object, options, defaults = nil)
1516
@headers = options[:headers] || {}
1617
@memo = options[:memo] || {}
1718
@search_attributes = options[:search_attributes] || {}
19+
@start_delay = options[:start_delay] || 0
1820

1921
# For Temporal::Workflow and Temporal::Activity use defined values as the next option
2022
if has_executable_concern?(object)

spec/unit/lib/temporal/client_spec.rb

+23-14
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,21 @@ def inject!(header)
5252
subject.start_workflow(TestStartWorkflow, 42)
5353
expect(connection)
5454
.to have_received(:start_workflow_execution)
55-
.with(
56-
namespace: 'default-test-namespace',
57-
workflow_id: an_instance_of(String),
58-
workflow_name: 'TestStartWorkflow',
59-
task_queue: 'default-test-task-queue',
60-
input: [42],
61-
task_timeout: config.timeouts[:task],
62-
run_timeout: config.timeouts[:run],
63-
execution_timeout: config.timeouts[:execution],
64-
workflow_id_reuse_policy: nil,
65-
headers: { 'test' => 'asdf' },
66-
memo: {},
67-
search_attributes: {},
68-
)
55+
.with(
56+
namespace: 'default-test-namespace',
57+
workflow_id: an_instance_of(String),
58+
workflow_name: 'TestStartWorkflow',
59+
task_queue: 'default-test-task-queue',
60+
input: [42],
61+
task_timeout: config.timeouts[:task],
62+
run_timeout: config.timeouts[:run],
63+
execution_timeout: config.timeouts[:execution],
64+
workflow_id_reuse_policy: nil,
65+
headers: { 'test' => 'asdf' },
66+
memo: {},
67+
search_attributes: {},
68+
start_delay: 0
69+
)
6970
end
7071
end
7172

@@ -94,6 +95,7 @@ def inject!(header)
9495
headers: {},
9596
memo: {},
9697
search_attributes: {},
98+
start_delay: 0
9799
)
98100
end
99101

@@ -109,6 +111,7 @@ def inject!(header)
109111
workflow_id_reuse_policy: :reject,
110112
memo: { 'MemoKey1' => 'MemoValue1' },
111113
search_attributes: { 'SearchAttribute1' => 256 },
114+
start_delay: 10
112115
}
113116
)
114117

@@ -127,6 +130,7 @@ def inject!(header)
127130
headers: { 'Foo' => 'Bar' },
128131
memo: { 'MemoKey1' => 'MemoValue1' },
129132
search_attributes: { 'SearchAttribute1' => 256 },
133+
start_delay: 10
130134
)
131135
end
132136

@@ -154,6 +158,7 @@ def inject!(header)
154158
headers: {},
155159
memo: {},
156160
search_attributes: {},
161+
start_delay: 0
157162
)
158163
end
159164

@@ -175,6 +180,7 @@ def inject!(header)
175180
headers: {},
176181
memo: {},
177182
search_attributes: {},
183+
start_delay: 0
178184
)
179185
end
180186

@@ -198,6 +204,7 @@ def inject!(header)
198204
headers: {},
199205
memo: {},
200206
search_attributes: {},
207+
start_delay: 0
201208
)
202209
end
203210
end
@@ -225,6 +232,7 @@ def inject!(header)
225232
headers: {},
226233
memo: {},
227234
search_attributes: {},
235+
start_delay: 0
228236
)
229237
end
230238
end
@@ -255,6 +263,7 @@ def expect_signal_with_start(expected_arguments, expected_signal_argument)
255263
search_attributes: {},
256264
signal_name: 'the question',
257265
signal_input: expected_signal_argument,
266+
start_delay: 0
258267
)
259268
end
260269

spec/unit/lib/temporal/execution_options_spec.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,11 @@ class TestExecutionOptionsWorkflow < Temporal::Workflow
9999
task_queue: 'test-task-queue',
100100
retry_policy: { interval: 1, backoff: 2, max_attempts: 5 },
101101
timeouts: { start_to_close: 10 },
102-
headers: { 'TestHeader' => 'Test' }
102+
headers: { 'TestHeader' => 'Test' },
103+
start_delay: 10
103104
}
104105
end
105-
106+
106107
it 'is initialized with full options' do
107108
expect(subject.name).to eq(options[:name])
108109
expect(subject.namespace).to eq(options[:namespace])
@@ -113,12 +114,13 @@ class TestExecutionOptionsWorkflow < Temporal::Workflow
113114
expect(subject.retry_policy.max_attempts).to eq(options[:retry_policy][:max_attempts])
114115
expect(subject.timeouts).to eq(options[:timeouts])
115116
expect(subject.headers).to eq(options[:headers])
117+
expect(subject.start_delay).to eq(options[:start_delay])
116118
end
117119
end
118-
120+
119121
context 'when retry policy options are invalid' do
120122
let(:options) { { retry_policy: { max_attempts: 10 } } }
121-
123+
122124
it 'raises' do
123125
expect { subject }.to raise_error(
124126
Temporal::RetryPolicy::InvalidRetryPolicy,

spec/unit/lib/temporal/grpc_spec.rb

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
execution_timeout: 1,
6767
run_timeout: 2,
6868
task_timeout: 3,
69+
start_delay: 10,
6970
memo: {},
7071
search_attributes: {
7172
'foo-int-attribute' => 256,
@@ -90,6 +91,7 @@
9091
expect(request.workflow_execution_timeout.seconds).to eq(1)
9192
expect(request.workflow_run_timeout.seconds).to eq(2)
9293
expect(request.workflow_task_timeout.seconds).to eq(3)
94+
expect(request.workflow_start_delay.seconds).to eq(10)
9395
expect(request.workflow_id_reuse_policy).to eq(:WORKFLOW_ID_REUSE_POLICY_REJECT_DUPLICATE)
9496
expect(request.search_attributes.indexed_fields).to eq({
9597
'foo-int-attribute' => Temporalio::Api::Common::V1::Payload.new(data: '256', metadata: { 'encoding' => 'json/plain' }),
@@ -138,6 +140,7 @@
138140
execution_timeout: 1,
139141
run_timeout: 2,
140142
task_timeout: 3,
143+
start_delay: 10,
141144
workflow_id_reuse_policy: :allow,
142145
signal_name: 'the question',
143146
signal_input: 'what do you get if you multiply six by nine?'
@@ -153,6 +156,7 @@
153156
expect(request.workflow_execution_timeout.seconds).to eq(1)
154157
expect(request.workflow_run_timeout.seconds).to eq(2)
155158
expect(request.workflow_task_timeout.seconds).to eq(3)
159+
expect(request.workflow_start_delay.seconds).to eq(10)
156160
expect(request.signal_name).to eq('the question')
157161
expect(request.signal_input.payloads[0].data).to eq('"what do you get if you multiply six by nine?"')
158162
expect(request.workflow_id_reuse_policy).to eq(:WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE)

0 commit comments

Comments
 (0)