smplkit 3.0.119 → 3.0.120
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.
- checksums.yaml +4 -4
- data/lib/smplkit/jobs/client.rb +198 -18
- data/lib/smplkit/jobs/models.rb +298 -9
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f21cdd3b499aaffa45dbf92b679ed06324dd8c7f07a3e43ff72e24702be9cc30
|
|
4
|
+
data.tar.gz: 45a58c59df05b11c74a661f64c470e29aa7676d3e976107335d051384b8f6497
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2aa8129c15ef6c1e687a36b3672118c84aada54a01632816fef22d297c55424a69b12ae34c9e93757ea3115099ac8871094e67981c25c709f4c25fbdd80c7df8
|
|
7
|
+
data.tar.gz: c4d07ee7e073dd6d1387743aa1431dbcbc3e526c66055204f8059f8e6f3ec4433009666fea7c69ad91de1ce84c97bd34e66927b56b6b03119132c01bc57c29e3
|
data/lib/smplkit/jobs/client.rb
CHANGED
|
@@ -12,8 +12,10 @@ require "time"
|
|
|
12
12
|
#
|
|
13
13
|
# client.jobs.{new_recurring_job,new_manual_job,schedule,get,list,delete,run,usage}
|
|
14
14
|
# client.jobs.runs.{list,get,cancel,rerun}
|
|
15
|
+
# client.jobs.retry_policies.{new,list,get,delete}
|
|
15
16
|
# Job#{save,delete,trigger,list_runs}
|
|
16
17
|
# Run#{rerun,cancel}
|
|
18
|
+
# RetryPolicy#{save,delete}
|
|
17
19
|
#
|
|
18
20
|
# A job is enabled per environment: a recurring (cron) job may be enabled in
|
|
19
21
|
# several environments at once, a manual job (no schedule) runs only when
|
|
@@ -47,16 +49,29 @@ module Smplkit
|
|
|
47
49
|
# any of these environment keys. +nil+ falls back to the client's
|
|
48
50
|
# configured environment (if any), otherwise covers every environment you
|
|
49
51
|
# can access.
|
|
52
|
+
# @param triggers [Array<String>, nil] Restrict to runs started by any of
|
|
53
|
+
# these triggers (see {RunTrigger}) — e.g. +[RunTrigger::RETRY]+ for
|
|
54
|
+
# automatic retries. Serialized as a comma-joined +filter[trigger]+
|
|
55
|
+
# (any-of). +nil+ or empty covers every trigger.
|
|
56
|
+
# @param last_run_only [Boolean] When +true+, collapse the result to the
|
|
57
|
+
# last completed (succeeded / failed / canceled) run per
|
|
58
|
+
# job-and-environment; in-flight runs are excluded. The other filters
|
|
59
|
+
# apply first, then the collapse. Defaults to +false+; the query param is
|
|
60
|
+
# sent only when +true+.
|
|
50
61
|
# @param page_size [Integer, nil] Maximum number of runs to return in this
|
|
51
62
|
# page. +nil+ uses the server default.
|
|
52
63
|
# @param after [String, nil] Opaque cursor from a previous page; returns
|
|
53
64
|
# the runs that follow it. +nil+ starts from the first page.
|
|
54
65
|
# @return [Array<Smplkit::Jobs::Run>] The runs in this page.
|
|
55
|
-
def list(job: nil, environments: nil, page_size: nil, after: nil)
|
|
66
|
+
def list(job: nil, environments: nil, triggers: nil, last_run_only: false, page_size: nil, after: nil)
|
|
56
67
|
opts = {}
|
|
57
68
|
opts[:filter_job] = job unless job.nil?
|
|
58
69
|
filter_environment = Jobs.resolve_environment_filter(environments, @environment)
|
|
59
70
|
opts[:filter_environment] = filter_environment unless filter_environment.nil?
|
|
71
|
+
opts[:filter_trigger] = triggers.join(",") unless triggers.nil? || triggers.empty?
|
|
72
|
+
# The generated default would emit +last_run_only=false+ on every call;
|
|
73
|
+
# send the param only when explicitly requested.
|
|
74
|
+
opts[:last_run_only] = true if last_run_only
|
|
60
75
|
opts[:page_size] = page_size unless page_size.nil?
|
|
61
76
|
opts[:page_after] = after unless after.nil?
|
|
62
77
|
|
|
@@ -94,6 +109,144 @@ module Smplkit
|
|
|
94
109
|
end
|
|
95
110
|
end
|
|
96
111
|
|
|
112
|
+
# +client.jobs.retry_policies.*+ — manage reusable, account-global retry
|
|
113
|
+
# policies.
|
|
114
|
+
#
|
|
115
|
+
# A {RetryPolicy} is an active record: build one with {#new}, set fields, and
|
|
116
|
+
# call +#save+; then reference it from a job's +retry_policy+ (see
|
|
117
|
+
# {JobsClient#new_recurring_job} and {Job#set_retry_policy}). Retry policies
|
|
118
|
+
# are account-global — never environment-scoped.
|
|
119
|
+
class RetryPoliciesClient
|
|
120
|
+
# @param api [SmplkitGeneratedClient::Jobs::RetryPoliciesApi] The generated
|
|
121
|
+
# retry-policies API.
|
|
122
|
+
def initialize(api)
|
|
123
|
+
@api = api
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Construct an unsaved {RetryPolicy} bound to this client. Call +#save+ on
|
|
127
|
+
# the returned instance to create it.
|
|
128
|
+
#
|
|
129
|
+
# @param id [String] Caller-supplied unique identifier for the policy.
|
|
130
|
+
# Unique within the account and immutable; the service returns 409 if
|
|
131
|
+
# another live policy already uses this id.
|
|
132
|
+
# @param name [String] Human-readable name for the policy.
|
|
133
|
+
# @param max_retries [Integer] How many times a failed run is retried after
|
|
134
|
+
# the initial attempt — +3+ means up to 4 attempts total. +0+ disables
|
|
135
|
+
# retries. Maximum 10.
|
|
136
|
+
# @param backoff [String] How the wait between retries grows; one of
|
|
137
|
+
# {Backoff}.
|
|
138
|
+
# @param delay_seconds [Integer] The wait before a retry, in seconds — the
|
|
139
|
+
# constant wait for {Backoff::FIXED}, or the base that doubles each retry
|
|
140
|
+
# for {Backoff::EXPONENTIAL}.
|
|
141
|
+
# @param max_delay_seconds [Integer, nil] Ceiling on the wait between
|
|
142
|
+
# retries, for {Backoff::EXPONENTIAL} backoff only. +nil+ (the default)
|
|
143
|
+
# leaves it uncapped; omit it for {Backoff::FIXED}.
|
|
144
|
+
# @param retry_on [RetryOn, nil] Which failures to retry (see {RetryOn}).
|
|
145
|
+
# +nil+ (the default) retries nothing.
|
|
146
|
+
# @return [Smplkit::Jobs::RetryPolicy]
|
|
147
|
+
def new(id, name:, max_retries:, backoff:, delay_seconds:, max_delay_seconds: nil, retry_on: nil)
|
|
148
|
+
RetryPolicy.new(
|
|
149
|
+
self,
|
|
150
|
+
id: id, name: name, max_retries: max_retries, backoff: backoff,
|
|
151
|
+
delay_seconds: delay_seconds, max_delay_seconds: max_delay_seconds, retry_on: retry_on
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# List retry policies in the account.
|
|
156
|
+
#
|
|
157
|
+
# @param name [String, nil] Return only policies whose name contains this
|
|
158
|
+
# text (case-insensitive). +nil+ lists all.
|
|
159
|
+
# @param page_number [Integer, nil] 1-based page to return. +nil+ returns
|
|
160
|
+
# the first page.
|
|
161
|
+
# @param page_size [Integer, nil] Maximum number of policies to return in
|
|
162
|
+
# this page. +nil+ uses the server default.
|
|
163
|
+
# @return [Array<Smplkit::Jobs::RetryPolicy>] The policies in this page.
|
|
164
|
+
def list(name: nil, page_number: nil, page_size: nil)
|
|
165
|
+
opts = {}
|
|
166
|
+
opts[:filter_name] = name unless name.nil?
|
|
167
|
+
opts[:page_number] = page_number unless page_number.nil?
|
|
168
|
+
opts[:page_size] = page_size unless page_size.nil?
|
|
169
|
+
|
|
170
|
+
resp = Jobs.call_api { @api.list_retry_policies(opts) }
|
|
171
|
+
(resp.data || []).map { |r| RetryPolicy.from_resource(r, client: self) }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Fetch a single retry policy by its id.
|
|
175
|
+
#
|
|
176
|
+
# @param id [String] Identifier of the policy to fetch.
|
|
177
|
+
# @return [Smplkit::Jobs::RetryPolicy] The matching policy.
|
|
178
|
+
# @raise [Smplkit::NotFoundError] when no policy with this id exists.
|
|
179
|
+
def get(id)
|
|
180
|
+
resp = Jobs.call_api { @api.get_retry_policy(id) }
|
|
181
|
+
RetryPolicy.from_resource(resp.data, client: self)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Delete a retry policy by its id.
|
|
185
|
+
#
|
|
186
|
+
# @param id [String] Identifier of the policy to delete.
|
|
187
|
+
# @return [nil]
|
|
188
|
+
def delete(id)
|
|
189
|
+
Jobs.call_api { @api.delete_retry_policy(id) }
|
|
190
|
+
nil
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# @api private — POST a new retry policy. Called by {RetryPolicy#save} on
|
|
194
|
+
# unsaved instances. The jobs service requires a caller-supplied
|
|
195
|
+
# +data.id+ on create and 409s on conflict.
|
|
196
|
+
def _create_retry_policy(policy)
|
|
197
|
+
if policy.id.nil? || policy.id.empty?
|
|
198
|
+
raise ArgumentError, "RetryPolicy.id is required on create (caller-supplied key)"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
resp = Jobs.call_api { @api.create_retry_policy(build_create_body(policy)) }
|
|
202
|
+
RetryPolicy.from_resource(resp.data, client: self)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# @api private — Full-replace PUT for an existing retry policy. Called by
|
|
206
|
+
# {RetryPolicy#save} on instances with +created_at+.
|
|
207
|
+
def _update_retry_policy(policy)
|
|
208
|
+
raise ArgumentError, "cannot update a RetryPolicy with no id" if policy.id.nil?
|
|
209
|
+
|
|
210
|
+
resp = Jobs.call_api { @api.update_retry_policy(policy.id, build_body(policy)) }
|
|
211
|
+
RetryPolicy.from_resource(resp.data, client: self)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
private
|
|
215
|
+
|
|
216
|
+
# Build the generated attributes model shared by create and update. The
|
|
217
|
+
# +retry_on+ failure set is always sent; +max_delay_seconds+ is sent only
|
|
218
|
+
# when present (omitting it leaves the policy uncapped / is invalid for
|
|
219
|
+
# fixed backoff).
|
|
220
|
+
def build_retry_policy_attrs(policy)
|
|
221
|
+
attrs = {
|
|
222
|
+
name: policy.name,
|
|
223
|
+
max_retries: policy.max_retries,
|
|
224
|
+
backoff: policy.backoff,
|
|
225
|
+
delay_seconds: policy.delay_seconds,
|
|
226
|
+
retry_on: RetryOn.to_wire(policy.retry_on)
|
|
227
|
+
}
|
|
228
|
+
attrs[:max_delay_seconds] = policy.max_delay_seconds unless policy.max_delay_seconds.nil?
|
|
229
|
+
SmplkitGeneratedClient::Jobs::RetryPolicy.new(attrs)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def build_create_body(policy)
|
|
233
|
+
# Create uses the distinct RetryPolicyCreateRequest envelope; the jobs
|
|
234
|
+
# service requires data.id (the caller-supplied key) on create.
|
|
235
|
+
resource = SmplkitGeneratedClient::Jobs::RetryPolicyCreateResource.new(
|
|
236
|
+
id: policy.id.to_s, type: "retry_policy", attributes: build_retry_policy_attrs(policy)
|
|
237
|
+
)
|
|
238
|
+
SmplkitGeneratedClient::Jobs::RetryPolicyCreateRequest.new(data: resource)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def build_body(policy)
|
|
242
|
+
# Update path uses the generic RetryPolicyRequest envelope.
|
|
243
|
+
resource = SmplkitGeneratedClient::Jobs::RetryPolicyResource.new(
|
|
244
|
+
id: policy.id.to_s, type: "retry_policy", attributes: build_retry_policy_attrs(policy)
|
|
245
|
+
)
|
|
246
|
+
SmplkitGeneratedClient::Jobs::RetryPolicyRequest.new(data: resource)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
97
250
|
# The Smpl Jobs client — accessed via +client.jobs+.
|
|
98
251
|
#
|
|
99
252
|
# Unlike Config/Flags/Logging, Jobs has no live "phone-home" agent — no
|
|
@@ -103,8 +256,10 @@ module Smplkit
|
|
|
103
256
|
#
|
|
104
257
|
# client.jobs.{new_recurring_job,new_manual_job,schedule,get,list,delete,run,usage}
|
|
105
258
|
# client.jobs.runs.{list,get,cancel,rerun}
|
|
259
|
+
# client.jobs.retry_policies.{new,list,get,delete}
|
|
106
260
|
# Job#{save,delete,trigger,list_runs}
|
|
107
261
|
# Run#{rerun,cancel}
|
|
262
|
+
# RetryPolicy#{save,delete}
|
|
108
263
|
#
|
|
109
264
|
# Build a standalone Smpl Jobs transport from resolved config.
|
|
110
265
|
#
|
|
@@ -139,6 +294,10 @@ module Smplkit
|
|
|
139
294
|
# @return [RunsClient] Run history and run actions (+client.jobs.runs+).
|
|
140
295
|
attr_reader :runs
|
|
141
296
|
|
|
297
|
+
# @return [RetryPoliciesClient] Reusable retry policies
|
|
298
|
+
# (+client.jobs.retry_policies+).
|
|
299
|
+
attr_reader :retry_policies
|
|
300
|
+
|
|
142
301
|
# @param api_key [String, nil] API key. When omitted, resolved from
|
|
143
302
|
# +SMPLKIT_API_KEY+ or +~/.smplkit+.
|
|
144
303
|
# @param profile [String, nil] Named +~/.smplkit+ profile section.
|
|
@@ -164,6 +323,7 @@ module Smplkit
|
|
|
164
323
|
@environment = environment
|
|
165
324
|
@api = SmplkitGeneratedClient::Jobs::JobsApi.new(auth)
|
|
166
325
|
@runs = RunsClient.new(SmplkitGeneratedClient::Jobs::RunsApi.new(auth), environment: environment)
|
|
326
|
+
@retry_policies = RetryPoliciesClient.new(SmplkitGeneratedClient::Jobs::RetryPoliciesApi.new(auth))
|
|
167
327
|
@usage_api = SmplkitGeneratedClient::Jobs::UsageApi.new(auth)
|
|
168
328
|
end
|
|
169
329
|
|
|
@@ -191,8 +351,14 @@ module Smplkit
|
|
|
191
351
|
# live job already uses this id.
|
|
192
352
|
# @param name [String] Human-readable name for the job.
|
|
193
353
|
# @param schedule [String] The base cadence — a 5-field cron expression
|
|
194
|
-
# evaluated in UTC
|
|
195
|
-
# unless it sets its own override.
|
|
354
|
+
# evaluated in the job's +timezone+ (UTC by default), e.g. +"0 2 * * *"+ —
|
|
355
|
+
# that every environment inherits unless it sets its own override.
|
|
356
|
+
# @param timezone [String, nil] Base IANA timezone the cron +schedule+ is
|
|
357
|
+
# evaluated in (e.g. +"America/New_York"+), DST-aware. +nil+ (the default)
|
|
358
|
+
# means UTC. Every environment inherits it unless it overrides it.
|
|
359
|
+
# @param retry_policy [String, nil] Base retry policy for failed runs — the
|
|
360
|
+
# id of a {Smplkit::Jobs::RetryPolicy}, overridable per environment. +nil+
|
|
361
|
+
# (the default) uses the built-in +"Default"+ policy, which never retries.
|
|
196
362
|
# @param configuration [Smplkit::Jobs::HttpConfig] The HTTP request the job
|
|
197
363
|
# sends each time it fires.
|
|
198
364
|
# @param description [String, nil] Optional free-text description.
|
|
@@ -205,11 +371,11 @@ module Smplkit
|
|
|
205
371
|
# @param concurrency_policy [String] How overlapping runs are handled.
|
|
206
372
|
# Defaults to +"ALLOW"+.
|
|
207
373
|
# @return [Smplkit::Jobs::Job]
|
|
208
|
-
def new_recurring_job(id, name:, schedule:, configuration:,
|
|
209
|
-
environments: nil, concurrency_policy: "ALLOW")
|
|
374
|
+
def new_recurring_job(id, name:, schedule:, configuration:, timezone: nil, retry_policy: nil,
|
|
375
|
+
description: nil, environments: nil, concurrency_policy: "ALLOW")
|
|
210
376
|
_new_job(
|
|
211
|
-
id, name: name, schedule: schedule,
|
|
212
|
-
description: description, environments: environments,
|
|
377
|
+
id, name: name, schedule: schedule, timezone: timezone, retry_policy: retry_policy,
|
|
378
|
+
configuration: configuration, description: description, environments: environments,
|
|
213
379
|
concurrency_policy: concurrency_policy, environment: nil
|
|
214
380
|
)
|
|
215
381
|
end
|
|
@@ -234,12 +400,15 @@ module Smplkit
|
|
|
234
400
|
# override). The job is triggerable only in environments enabled here.
|
|
235
401
|
# @param concurrency_policy [String] How overlapping runs are handled.
|
|
236
402
|
# Defaults to +"ALLOW"+.
|
|
403
|
+
# @param retry_policy [String, nil] Retry policy for failed runs — the id of
|
|
404
|
+
# a {Smplkit::Jobs::RetryPolicy}, overridable per environment. +nil+ (the
|
|
405
|
+
# default) uses the built-in +"Default"+ policy, which never retries.
|
|
237
406
|
# @return [Smplkit::Jobs::Job]
|
|
238
407
|
def new_manual_job(id, name:, configuration:, description: nil,
|
|
239
|
-
environments: nil, concurrency_policy: "ALLOW")
|
|
408
|
+
environments: nil, concurrency_policy: "ALLOW", retry_policy: nil)
|
|
240
409
|
_new_job(
|
|
241
|
-
id, name: name, schedule: nil,
|
|
242
|
-
description: description, environments: environments,
|
|
410
|
+
id, name: name, schedule: nil, retry_policy: retry_policy,
|
|
411
|
+
configuration: configuration, description: description, environments: environments,
|
|
243
412
|
concurrency_policy: concurrency_policy, environment: nil
|
|
244
413
|
)
|
|
245
414
|
end
|
|
@@ -259,14 +428,17 @@ module Smplkit
|
|
|
259
428
|
# @param description [String, nil] Optional free-text description.
|
|
260
429
|
# @param concurrency_policy [String] How overlapping runs are handled.
|
|
261
430
|
# Defaults to +"ALLOW"+.
|
|
431
|
+
# @param retry_policy [String, nil] Retry policy for failed runs — the id of
|
|
432
|
+
# a {Smplkit::Jobs::RetryPolicy}. +nil+ (the default) uses the built-in
|
|
433
|
+
# +"Default"+ policy, which never retries.
|
|
262
434
|
# @param environment [String, nil] The environment the job is born in.
|
|
263
435
|
# Defaults to the client's configured environment.
|
|
264
436
|
# @return [Smplkit::Jobs::Job]
|
|
265
437
|
def schedule(id, name:, schedule:, configuration:, description: nil,
|
|
266
|
-
concurrency_policy: "ALLOW", environment: nil)
|
|
438
|
+
concurrency_policy: "ALLOW", retry_policy: nil, environment: nil)
|
|
267
439
|
_new_job(
|
|
268
|
-
id, name: name, schedule: schedule.iso8601,
|
|
269
|
-
description: description, environments: nil,
|
|
440
|
+
id, name: name, schedule: schedule.iso8601, retry_policy: retry_policy,
|
|
441
|
+
configuration: configuration, description: description, environments: nil,
|
|
270
442
|
concurrency_policy: concurrency_policy, environment: environment
|
|
271
443
|
)
|
|
272
444
|
end
|
|
@@ -377,12 +549,15 @@ module Smplkit
|
|
|
377
549
|
# public constructors ({#new_recurring_job}, {#new_manual_job}, {#schedule})
|
|
378
550
|
# funnel through here.
|
|
379
551
|
def _new_job(id, name:, schedule:, configuration:, description:,
|
|
380
|
-
environments:, concurrency_policy:, environment
|
|
552
|
+
environments:, concurrency_policy:, environment:,
|
|
553
|
+
timezone: nil, retry_policy: nil)
|
|
381
554
|
Job.new(
|
|
382
555
|
self,
|
|
383
556
|
id: id,
|
|
384
557
|
name: name,
|
|
385
558
|
schedule: schedule,
|
|
559
|
+
timezone: timezone,
|
|
560
|
+
retry_policy: retry_policy,
|
|
386
561
|
configuration: configuration,
|
|
387
562
|
description: description,
|
|
388
563
|
environments: Jobs.normalize_environments(environments),
|
|
@@ -394,15 +569,17 @@ module Smplkit
|
|
|
394
569
|
# Convert the wrapper +environments+ map to the generated model hash.
|
|
395
570
|
#
|
|
396
571
|
# Each entry's +enabled+ is always written; a per-environment +schedule+
|
|
397
|
-
# (cron) override, +timezone+ override,
|
|
398
|
-
# each sent only when present (omit to inherit
|
|
399
|
-
# +
|
|
400
|
-
# +next_run_at+ is never
|
|
572
|
+
# (cron) override, +timezone+ override, +retry_policy+ override, and
|
|
573
|
+
# +configuration+ override are each sent only when present (omit to inherit
|
|
574
|
+
# the job's base +schedule+ / +timezone+ / +retry_policy+ /
|
|
575
|
+
# +configuration+). The read-only per-environment +next_run_at+ is never
|
|
576
|
+
# written.
|
|
401
577
|
def environments_to_wire(environments)
|
|
402
578
|
(environments || {}).each_with_object({}) do |(env_key, env), out|
|
|
403
579
|
attrs = { enabled: env.enabled }
|
|
404
580
|
attrs[:schedule] = env.schedule unless env.schedule.nil?
|
|
405
581
|
attrs[:timezone] = env.timezone unless env.timezone.nil?
|
|
582
|
+
attrs[:retry_policy] = env.retry_policy unless env.retry_policy.nil?
|
|
406
583
|
attrs[:configuration] = HttpConfig.to_wire(env.configuration) unless env.configuration.nil?
|
|
407
584
|
out[env_key.to_s] = SmplkitGeneratedClient::Jobs::JobEnvironment.new(attrs)
|
|
408
585
|
end
|
|
@@ -425,6 +602,9 @@ module Smplkit
|
|
|
425
602
|
# explicit +null+ creates a manual job, omitting +timezone+ simply
|
|
426
603
|
# inherits UTC — so it is sent only when present.)
|
|
427
604
|
attrs[:timezone] = job.timezone unless job.timezone.nil?
|
|
605
|
+
# +retry_policy+ id; an unset +nil+ is omitted, leaving the server
|
|
606
|
+
# default (the built-in +Default+ policy, which never retries).
|
|
607
|
+
attrs[:retry_policy] = job.retry_policy unless job.retry_policy.nil?
|
|
428
608
|
environments = job.environments
|
|
429
609
|
attrs[:environments] = environments_to_wire(environments) unless environments.nil? || environments.empty?
|
|
430
610
|
SmplkitGeneratedClient::Jobs::Job.new(attrs)
|
data/lib/smplkit/jobs/models.rb
CHANGED
|
@@ -79,8 +79,8 @@ module Smplkit
|
|
|
79
79
|
# (+{ enabled: true, schedule: "0 3 * * *", configuration: HttpConfig.new(...) }+)
|
|
80
80
|
# so callers can use the lightweight hash form without importing the model. A
|
|
81
81
|
# dict-form +configuration+ override is coerced to an {HttpConfig} so it
|
|
82
|
-
# serializes on save; optional +schedule+ cron
|
|
83
|
-
# through.
|
|
82
|
+
# serializes on save; optional +schedule+ cron, +timezone+, and
|
|
83
|
+
# +retry_policy+ overrides pass through.
|
|
84
84
|
#
|
|
85
85
|
# @api private
|
|
86
86
|
def self.normalize_environments(environments)
|
|
@@ -96,6 +96,7 @@ module Smplkit
|
|
|
96
96
|
enabled: value[:enabled] || value["enabled"] || false,
|
|
97
97
|
schedule: value[:schedule] || value["schedule"],
|
|
98
98
|
timezone: value[:timezone] || value["timezone"],
|
|
99
|
+
retry_policy: value[:retry_policy] || value["retry_policy"],
|
|
99
100
|
configuration: cfg
|
|
100
101
|
)
|
|
101
102
|
end
|
|
@@ -120,13 +121,40 @@ module Smplkit
|
|
|
120
121
|
#
|
|
121
122
|
# - +MANUAL+: A +run+ / +trigger+ call started it on demand.
|
|
122
123
|
# - +RERUN+: It repeats an earlier run.
|
|
124
|
+
# - +RETRY+: An automatic retry of a failed run, per the job's retry policy.
|
|
123
125
|
# - +SCHEDULE+: The job's schedule fired.
|
|
124
126
|
module RunTrigger
|
|
125
127
|
MANUAL = "MANUAL"
|
|
126
128
|
RERUN = "RERUN"
|
|
129
|
+
RETRY = "RETRY"
|
|
127
130
|
SCHEDULE = "SCHEDULE"
|
|
128
131
|
|
|
129
|
-
VALUES = [MANUAL, RERUN, SCHEDULE].freeze
|
|
132
|
+
VALUES = [MANUAL, RERUN, RETRY, SCHEDULE].freeze
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# How the wait between retries grows (a retry policy's backoff strategy).
|
|
136
|
+
#
|
|
137
|
+
# - +EXPONENTIAL+: Double the wait each retry — +delay_seconds+, then +2×+,
|
|
138
|
+
# +4×+, … — capped at +max_delay_seconds+.
|
|
139
|
+
# - +FIXED+: Wait a constant +delay_seconds+ before every retry.
|
|
140
|
+
module Backoff
|
|
141
|
+
EXPONENTIAL = "exponential"
|
|
142
|
+
FIXED = "fixed"
|
|
143
|
+
|
|
144
|
+
VALUES = [EXPONENTIAL, FIXED].freeze
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# A failure category a retry policy can retry on.
|
|
148
|
+
#
|
|
149
|
+
# - +CONNECTION_ERROR+: The endpoint could not be reached.
|
|
150
|
+
# - +NON_SUCCESS_STATUS+: Any non-success response, regardless of +statuses+.
|
|
151
|
+
# - +TIMEOUT+: The run did not complete in time.
|
|
152
|
+
module RetryReason
|
|
153
|
+
CONNECTION_ERROR = "CONNECTION_ERROR"
|
|
154
|
+
NON_SUCCESS_STATUS = "NON_SUCCESS_STATUS"
|
|
155
|
+
TIMEOUT = "TIMEOUT"
|
|
156
|
+
|
|
157
|
+
VALUES = [CONNECTION_ERROR, NON_SUCCESS_STATUS, TIMEOUT].freeze
|
|
130
158
|
end
|
|
131
159
|
|
|
132
160
|
# HTTP verb a job uses when it fires.
|
|
@@ -159,6 +187,46 @@ module Smplkit
|
|
|
159
187
|
end
|
|
160
188
|
end
|
|
161
189
|
|
|
190
|
+
# Which failures a retry policy retries. An empty {RetryOn} (both lists
|
|
191
|
+
# empty) retries nothing.
|
|
192
|
+
#
|
|
193
|
+
# @!attribute [rw] statuses
|
|
194
|
+
# @return [Array<Integer>] Response status codes to retry when a run fails
|
|
195
|
+
# because the response did not match the job's success status (e.g.
|
|
196
|
+
# +[429, 503]+ for rate-limit and unavailable). Each is a 3-digit HTTP
|
|
197
|
+
# code. Defaults to an empty list.
|
|
198
|
+
# @!attribute [rw] reasons
|
|
199
|
+
# @return [Array<String>] Failure categories to retry — see {RetryReason}.
|
|
200
|
+
# Defaults to an empty list.
|
|
201
|
+
RetryOn = Struct.new(:statuses, :reasons, keyword_init: true) do
|
|
202
|
+
def initialize(statuses: nil, reasons: nil)
|
|
203
|
+
super(statuses: statuses || [], reasons: reasons || [])
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# @api private — Convert a {RetryOn} into the generated wire model.
|
|
207
|
+
# Reasons are serialized as their raw string values.
|
|
208
|
+
#
|
|
209
|
+
# @param src [RetryOn] The failure set to serialize.
|
|
210
|
+
# @return [SmplkitGeneratedClient::Jobs::RetryOn] The wire model.
|
|
211
|
+
def self.to_wire(src)
|
|
212
|
+
SmplkitGeneratedClient::Jobs::RetryOn.new(
|
|
213
|
+
statuses: Array(src.statuses),
|
|
214
|
+
reasons: Array(src.reasons).map(&:to_s)
|
|
215
|
+
)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# @api private — Build a {RetryOn} from the generated wire model. A +nil+
|
|
219
|
+
# wire value (the field was absent) yields an empty {RetryOn}.
|
|
220
|
+
#
|
|
221
|
+
# @param src [SmplkitGeneratedClient::Jobs::RetryOn, nil] The wire model.
|
|
222
|
+
# @return [RetryOn]
|
|
223
|
+
def self.from_wire(src)
|
|
224
|
+
return new if src.nil?
|
|
225
|
+
|
|
226
|
+
new(statuses: src.statuses || [], reasons: src.reasons || [])
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
162
230
|
# A single name/value HTTP header on the request a job performs.
|
|
163
231
|
#
|
|
164
232
|
# @!attribute [rw] name
|
|
@@ -300,6 +368,10 @@ module Smplkit
|
|
|
300
368
|
# present, it must be a valid IANA zone key (e.g. +"America/New_York"+);
|
|
301
369
|
# it may be set on an environment that inherits the base schedule (it
|
|
302
370
|
# need not also override {#schedule}). Sent on writes only when present.
|
|
371
|
+
# @!attribute [rw] retry_policy
|
|
372
|
+
# @return [String, nil] Optional per-environment retry-policy override — the
|
|
373
|
+
# id of a {RetryPolicy} (or +"Default"+). +nil+ (the default) inherits the
|
|
374
|
+
# job's base {Job#retry_policy}. Sent on writes only when present.
|
|
303
375
|
# @!attribute [rw] configuration
|
|
304
376
|
# @return [HttpConfig, nil] Optional per-environment request configuration
|
|
305
377
|
# that fully replaces the job's base {Job#configuration} for this
|
|
@@ -310,8 +382,11 @@ module Smplkit
|
|
|
310
382
|
# @return [String, nil] Read-only. The next scheduled fire time in this
|
|
311
383
|
# environment. +nil+ when the environment is not enabled, or once a
|
|
312
384
|
# one-off run has fired. Never written back on save.
|
|
313
|
-
JobEnvironment = Struct.new(
|
|
314
|
-
|
|
385
|
+
JobEnvironment = Struct.new(
|
|
386
|
+
:enabled, :schedule, :timezone, :retry_policy, :configuration, :next_run_at, keyword_init: true
|
|
387
|
+
) do
|
|
388
|
+
def initialize(enabled: false, schedule: nil, timezone: nil, retry_policy: nil,
|
|
389
|
+
configuration: nil, next_run_at: nil)
|
|
315
390
|
super
|
|
316
391
|
end
|
|
317
392
|
|
|
@@ -328,6 +403,7 @@ module Smplkit
|
|
|
328
403
|
enabled: src.enabled.nil? ? false : src.enabled,
|
|
329
404
|
schedule: src.schedule,
|
|
330
405
|
timezone: src.timezone,
|
|
406
|
+
retry_policy: src.retry_policy,
|
|
331
407
|
configuration: cfg.nil? ? nil : HttpConfig.from_wire(cfg),
|
|
332
408
|
next_run_at: src.next_run_at
|
|
333
409
|
)
|
|
@@ -406,6 +482,13 @@ module Smplkit
|
|
|
406
482
|
# present.
|
|
407
483
|
attr_accessor :timezone
|
|
408
484
|
|
|
485
|
+
# @return [String, nil] The base retry policy for failed runs — the id of a
|
|
486
|
+
# {RetryPolicy}, overridable per environment via
|
|
487
|
+
# {JobEnvironment#retry_policy}. +nil+ (the default, omitted on the wire)
|
|
488
|
+
# uses the built-in +"Default"+ policy, which never retries. Set it with
|
|
489
|
+
# {#set_retry_policy}; sent on writes only when present.
|
|
490
|
+
attr_accessor :retry_policy
|
|
491
|
+
|
|
409
492
|
# @return [HttpConfig] The base HTTP request to perform when the job fires.
|
|
410
493
|
# Per-environment overrides live in {#environments}.
|
|
411
494
|
attr_accessor :configuration
|
|
@@ -436,7 +519,7 @@ module Smplkit
|
|
|
436
519
|
attr_accessor :birth_environment
|
|
437
520
|
|
|
438
521
|
def initialize(client = nil, id:, name:, configuration:, schedule: nil,
|
|
439
|
-
timezone: nil, description: nil, environments: nil,
|
|
522
|
+
timezone: nil, retry_policy: nil, description: nil, environments: nil,
|
|
440
523
|
kind: nil, type: "http", concurrency_policy: "ALLOW",
|
|
441
524
|
birth_environment: nil, created_at: nil,
|
|
442
525
|
updated_at: nil, deleted_at: nil, version: nil)
|
|
@@ -449,6 +532,7 @@ module Smplkit
|
|
|
449
532
|
@type = type
|
|
450
533
|
@schedule = schedule
|
|
451
534
|
@timezone = timezone
|
|
535
|
+
@retry_policy = retry_policy
|
|
452
536
|
@configuration = configuration
|
|
453
537
|
@concurrency_policy = concurrency_policy
|
|
454
538
|
@birth_environment = birth_environment
|
|
@@ -588,17 +672,27 @@ module Smplkit
|
|
|
588
672
|
# the cadence within that environment; it cannot turn a one-off job
|
|
589
673
|
# recurring or vice-versa. Call {#save} to persist.
|
|
590
674
|
#
|
|
675
|
+
# Because the timezone is an integral part of a cron cadence, a +timezone+
|
|
676
|
+
# may be supplied alongside the schedule; when given it sets the same
|
|
677
|
+
# scope's timezone too (equivalent to a follow-up {#set_timezone}). Omit it
|
|
678
|
+
# to leave the timezone untouched. For a timezone-only change, use
|
|
679
|
+
# {#set_timezone}.
|
|
680
|
+
#
|
|
591
681
|
# @param schedule [String] An ISO-8601 datetime, a 5-field UTC cron
|
|
592
682
|
# expression, or the literal +"now"+ (base); a 5-field UTC cron
|
|
593
683
|
# expression (per-environment).
|
|
684
|
+
# @param timezone [String, nil] An optional IANA timezone to set on the
|
|
685
|
+
# same scope (recurring jobs only). +nil+ (the default) leaves the
|
|
686
|
+
# timezone untouched.
|
|
594
687
|
# @param environment [String, nil] An environment key for a per-environment
|
|
595
688
|
# override, or +nil+ to set the base schedule.
|
|
596
|
-
def set_schedule(schedule, environment: nil)
|
|
689
|
+
def set_schedule(schedule, timezone: nil, environment: nil)
|
|
597
690
|
if environment.nil?
|
|
598
691
|
@schedule = schedule
|
|
599
692
|
else
|
|
600
693
|
_environment_override(environment).schedule = schedule
|
|
601
694
|
end
|
|
695
|
+
set_timezone(timezone, environment: environment) unless timezone.nil?
|
|
602
696
|
end
|
|
603
697
|
|
|
604
698
|
# Set the IANA timezone the cron schedule is evaluated in — base
|
|
@@ -624,6 +718,31 @@ module Smplkit
|
|
|
624
718
|
end
|
|
625
719
|
end
|
|
626
720
|
|
|
721
|
+
# Set the retry policy for failed runs — base (+environment+ omitted) or
|
|
722
|
+
# per-environment.
|
|
723
|
+
#
|
|
724
|
+
# With +environment+ omitted (the default), sets the base {#retry_policy}
|
|
725
|
+
# every environment inherits unless it overrides it. With an +environment+
|
|
726
|
+
# given, sets that environment's per-environment override on
|
|
727
|
+
# {#environments}, creating the override entry if it doesn't exist yet
|
|
728
|
+
# (preserving any already-set +enabled+ / +schedule+ / +timezone+ /
|
|
729
|
+
# +configuration+ on it). Call {#save} to persist.
|
|
730
|
+
#
|
|
731
|
+
# Accepts either a {RetryPolicy} instance (its id is used) or a policy id
|
|
732
|
+
# string — pass +"Default"+ for the built-in never-retry policy.
|
|
733
|
+
#
|
|
734
|
+
# @param retry_policy [RetryPolicy, String] A {RetryPolicy} or a policy id.
|
|
735
|
+
# @param environment [String, nil] An environment key for a per-environment
|
|
736
|
+
# override, or +nil+ to set the base retry policy.
|
|
737
|
+
def set_retry_policy(retry_policy, environment: nil)
|
|
738
|
+
policy_id = retry_policy.is_a?(RetryPolicy) ? retry_policy.id : retry_policy
|
|
739
|
+
if environment.nil?
|
|
740
|
+
@retry_policy = policy_id
|
|
741
|
+
else
|
|
742
|
+
_environment_override(environment).retry_policy = policy_id
|
|
743
|
+
end
|
|
744
|
+
end
|
|
745
|
+
|
|
627
746
|
# Trigger one immediate, manual run of this job (a +MANUAL+ run).
|
|
628
747
|
#
|
|
629
748
|
# @param environment [String, nil] Environment the run executes in.
|
|
@@ -641,17 +760,25 @@ module Smplkit
|
|
|
641
760
|
#
|
|
642
761
|
# @param environment [String, nil] Restrict to runs stamped with this
|
|
643
762
|
# environment. +nil+ covers every environment you can access.
|
|
763
|
+
# @param triggers [Array<String>, nil] Restrict to runs started by any of
|
|
764
|
+
# these triggers (see {RunTrigger}) — e.g. +[RunTrigger::RETRY]+ for
|
|
765
|
+
# automatic retries. +nil+ covers every trigger.
|
|
766
|
+
# @param last_run_only [Boolean] When +true+, return only the last
|
|
767
|
+
# completed run per environment (in-flight runs excluded). Defaults to
|
|
768
|
+
# +false+.
|
|
644
769
|
# @param page_size [Integer, nil] Maximum number of runs to return in this
|
|
645
770
|
# page.
|
|
646
771
|
# @param after [String, nil] Opaque cursor from a previous page.
|
|
647
772
|
# @return [Array<Smplkit::Jobs::Run>] The runs in this page.
|
|
648
773
|
# @raise [RuntimeError] when this job has no bound client.
|
|
649
|
-
def list_runs(environment: nil, page_size: nil, after: nil)
|
|
774
|
+
def list_runs(environment: nil, triggers: nil, last_run_only: false, page_size: nil, after: nil)
|
|
650
775
|
raise "Job was constructed without a client; cannot list runs" if @client.nil?
|
|
651
776
|
|
|
652
777
|
@client.runs.list(
|
|
653
778
|
job: @id,
|
|
654
779
|
environments: environment.nil? ? nil : [environment],
|
|
780
|
+
triggers: triggers,
|
|
781
|
+
last_run_only: last_run_only,
|
|
655
782
|
page_size: page_size,
|
|
656
783
|
after: after
|
|
657
784
|
)
|
|
@@ -678,6 +805,7 @@ module Smplkit
|
|
|
678
805
|
@type = other.type
|
|
679
806
|
@schedule = other.schedule
|
|
680
807
|
@timezone = other.timezone
|
|
808
|
+
@retry_policy = other.retry_policy
|
|
681
809
|
@configuration = other.configuration
|
|
682
810
|
@concurrency_policy = other.concurrency_policy
|
|
683
811
|
@created_at = other.created_at
|
|
@@ -709,6 +837,7 @@ module Smplkit
|
|
|
709
837
|
type: a.type || "http",
|
|
710
838
|
schedule: a.schedule,
|
|
711
839
|
timezone: a.timezone,
|
|
840
|
+
retry_policy: a.retry_policy,
|
|
712
841
|
configuration: HttpConfig.from_wire(a.configuration),
|
|
713
842
|
concurrency_policy: a.concurrency_policy || "ALLOW",
|
|
714
843
|
created_at: a.created_at,
|
|
@@ -719,6 +848,16 @@ module Smplkit
|
|
|
719
848
|
end
|
|
720
849
|
end
|
|
721
850
|
|
|
851
|
+
# Where a +RETRY+ run sits in its retry chain (read-only).
|
|
852
|
+
#
|
|
853
|
+
# @!attribute [rw] of
|
|
854
|
+
# @return [String] Id of the chain's original run — the first attempt that
|
|
855
|
+
# failed and started the chain.
|
|
856
|
+
# @!attribute [rw] attempt
|
|
857
|
+
# @return [Integer] Which retry this run is — +1+ for the first retry, +2+
|
|
858
|
+
# for the second, and so on.
|
|
859
|
+
RunRetry = Struct.new(:of, :attempt, keyword_init: true)
|
|
860
|
+
|
|
722
861
|
# A single execution of a job (read-only) with +rerun+ / +cancel+ actions.
|
|
723
862
|
#
|
|
724
863
|
# Runs are created and mutated by the jobs service, not by clients; clients
|
|
@@ -741,6 +880,9 @@ module Smplkit
|
|
|
741
880
|
# {RunTrigger} constants: +SCHEDULE+, +MANUAL+ (run now), or +RERUN+.
|
|
742
881
|
# @!attribute [rw] rerun_of
|
|
743
882
|
# @return [String, nil] The source run's id; set only when +trigger+ is +RERUN+.
|
|
883
|
+
# @!attribute [rw] retry
|
|
884
|
+
# @return [RunRetry, nil] Retry-chain position, populated only when
|
|
885
|
+
# +trigger+ is +RETRY+; +nil+ otherwise.
|
|
744
886
|
# @!attribute [rw] scheduled_for
|
|
745
887
|
# @return [String, nil] The intended fire time for a scheduled run; +nil+
|
|
746
888
|
# for manual / rerun runs.
|
|
@@ -767,7 +909,7 @@ module Smplkit
|
|
|
767
909
|
# @!attribute [rw] created_at
|
|
768
910
|
# @return [String, nil] When the run was enqueued (became +PENDING+).
|
|
769
911
|
Run = Struct.new(
|
|
770
|
-
:id, :job, :job_version, :environment, :trigger, :rerun_of, :scheduled_for,
|
|
912
|
+
:id, :job, :job_version, :environment, :trigger, :rerun_of, :retry, :scheduled_for,
|
|
771
913
|
:status, :started_at, :finished_at, :pending_duration_ms, :run_duration_ms,
|
|
772
914
|
:total_duration_ms, :failure_reason, :error, :request, :result, :created_at,
|
|
773
915
|
keyword_init: true
|
|
@@ -780,6 +922,12 @@ module Smplkit
|
|
|
780
922
|
# @return [Run] The hydrated run.
|
|
781
923
|
def self.from_resource(resource, runs: nil)
|
|
782
924
|
a = resource.attributes
|
|
925
|
+
# The retry-chain position is populated only on a +RETRY+ run; the
|
|
926
|
+
# generated model exposes it as +_retry+ (+retry+ is a Ruby keyword).
|
|
927
|
+
retry_chain = a._retry
|
|
928
|
+
retry_pos = if a.trigger == RunTrigger::RETRY && !retry_chain.nil?
|
|
929
|
+
RunRetry.new(of: retry_chain.of, attempt: retry_chain.attempt)
|
|
930
|
+
end
|
|
783
931
|
new(
|
|
784
932
|
id: resource.id,
|
|
785
933
|
job: a.job,
|
|
@@ -787,6 +935,7 @@ module Smplkit
|
|
|
787
935
|
environment: a.environment,
|
|
788
936
|
trigger: a.trigger,
|
|
789
937
|
rerun_of: a.rerun_of,
|
|
938
|
+
retry: retry_pos,
|
|
790
939
|
scheduled_for: a.scheduled_for,
|
|
791
940
|
status: a.status,
|
|
792
941
|
started_at: a.started_at,
|
|
@@ -857,5 +1006,145 @@ module Smplkit
|
|
|
857
1006
|
)
|
|
858
1007
|
end
|
|
859
1008
|
end
|
|
1009
|
+
|
|
1010
|
+
# A named, reusable automatic-retry policy.
|
|
1011
|
+
#
|
|
1012
|
+
# Active-record style: instantiate via +client.jobs.retry_policies.new(...)+,
|
|
1013
|
+
# mutate fields directly, and call {#save} to persist or {#delete} to remove.
|
|
1014
|
+
# Reference a saved policy from a job's {Job#retry_policy} (see
|
|
1015
|
+
# {JobsClient#new_recurring_job} and {Job#set_retry_policy}). Retry policies
|
|
1016
|
+
# are account-global — never environment-scoped.
|
|
1017
|
+
#
|
|
1018
|
+
# A policy decides whether and how a failed run is retried. A job that
|
|
1019
|
+
# references nothing uses the built-in +"Default"+ policy, which never
|
|
1020
|
+
# retries.
|
|
1021
|
+
class RetryPolicy
|
|
1022
|
+
# @return [String] Caller-supplied unique identifier for the policy (the
|
|
1023
|
+
# resource +id+). Unique within the account and immutable; the service
|
|
1024
|
+
# returns 409 if another live policy already uses this id.
|
|
1025
|
+
attr_accessor :id
|
|
1026
|
+
|
|
1027
|
+
# @return [String] Human-readable name for the policy.
|
|
1028
|
+
attr_accessor :name
|
|
1029
|
+
|
|
1030
|
+
# @return [Integer] How many times a failed run is retried after the
|
|
1031
|
+
# initial attempt — +3+ means up to 4 attempts total. +0+ disables
|
|
1032
|
+
# retries. Maximum 10.
|
|
1033
|
+
attr_accessor :max_retries
|
|
1034
|
+
|
|
1035
|
+
# @return [String] How the wait between retries grows; one of {Backoff}.
|
|
1036
|
+
attr_accessor :backoff
|
|
1037
|
+
|
|
1038
|
+
# @return [Integer] The wait before a retry, in seconds — the constant wait
|
|
1039
|
+
# for {Backoff::FIXED}, or the base that doubles each retry for
|
|
1040
|
+
# {Backoff::EXPONENTIAL}.
|
|
1041
|
+
attr_accessor :delay_seconds
|
|
1042
|
+
|
|
1043
|
+
# @return [Integer, nil] Ceiling on the wait between retries, for
|
|
1044
|
+
# {Backoff::EXPONENTIAL} backoff only. +nil+ (the default, omitted on the
|
|
1045
|
+
# wire) leaves it uncapped; omit it for {Backoff::FIXED}.
|
|
1046
|
+
attr_accessor :max_delay_seconds
|
|
1047
|
+
|
|
1048
|
+
# @return [RetryOn] Which failures to retry; an empty {RetryOn} retries
|
|
1049
|
+
# nothing. Defaults to empty.
|
|
1050
|
+
attr_accessor :retry_on
|
|
1051
|
+
|
|
1052
|
+
# @return [String, nil] ISO-8601 timestamp of first persist. +nil+ for an
|
|
1053
|
+
# unsaved instance.
|
|
1054
|
+
attr_accessor :created_at
|
|
1055
|
+
|
|
1056
|
+
# @return [String, nil] ISO-8601 timestamp of the most recent mutation.
|
|
1057
|
+
attr_accessor :updated_at
|
|
1058
|
+
|
|
1059
|
+
# @return [String, nil] Timestamp when the policy was deleted; +nil+ for
|
|
1060
|
+
# live policies.
|
|
1061
|
+
attr_accessor :deleted_at
|
|
1062
|
+
|
|
1063
|
+
# @return [Integer, nil] Monotonic version counter, bumped on every
|
|
1064
|
+
# server-side write.
|
|
1065
|
+
attr_accessor :version
|
|
1066
|
+
|
|
1067
|
+
def initialize(client = nil, id:, name:, max_retries:, backoff:, delay_seconds:,
|
|
1068
|
+
max_delay_seconds: nil, retry_on: nil, created_at: nil,
|
|
1069
|
+
updated_at: nil, deleted_at: nil, version: nil)
|
|
1070
|
+
@client = client
|
|
1071
|
+
@id = id
|
|
1072
|
+
@name = name
|
|
1073
|
+
@max_retries = max_retries
|
|
1074
|
+
@backoff = backoff
|
|
1075
|
+
@delay_seconds = delay_seconds
|
|
1076
|
+
@max_delay_seconds = max_delay_seconds
|
|
1077
|
+
@retry_on = retry_on || RetryOn.new
|
|
1078
|
+
@created_at = created_at
|
|
1079
|
+
@updated_at = updated_at
|
|
1080
|
+
@deleted_at = deleted_at
|
|
1081
|
+
@version = version
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
# Create this policy, or full-replace it if it already exists.
|
|
1085
|
+
#
|
|
1086
|
+
# Upsert behavior is driven by {#created_at}: a policy with no +created_at+
|
|
1087
|
+
# is created (POST); otherwise it's full-replace updated (PUT). After the
|
|
1088
|
+
# call, every field is refreshed from the server response.
|
|
1089
|
+
#
|
|
1090
|
+
# @return [self]
|
|
1091
|
+
def save
|
|
1092
|
+
raise "RetryPolicy was constructed without a client; cannot save" if @client.nil?
|
|
1093
|
+
|
|
1094
|
+
updated = @created_at.nil? ? @client._create_retry_policy(self) : @client._update_retry_policy(self)
|
|
1095
|
+
_apply(updated)
|
|
1096
|
+
self
|
|
1097
|
+
end
|
|
1098
|
+
alias save! save
|
|
1099
|
+
|
|
1100
|
+
# Delete this policy on the server.
|
|
1101
|
+
#
|
|
1102
|
+
# @return [nil]
|
|
1103
|
+
def delete
|
|
1104
|
+
raise "RetryPolicy was constructed without a client or id; cannot delete" if @client.nil? || @id.nil?
|
|
1105
|
+
|
|
1106
|
+
@client.delete(@id)
|
|
1107
|
+
end
|
|
1108
|
+
alias delete! delete
|
|
1109
|
+
|
|
1110
|
+
# @api private
|
|
1111
|
+
def _apply(other)
|
|
1112
|
+
@id = other.id
|
|
1113
|
+
@name = other.name
|
|
1114
|
+
@max_retries = other.max_retries
|
|
1115
|
+
@backoff = other.backoff
|
|
1116
|
+
@delay_seconds = other.delay_seconds
|
|
1117
|
+
@max_delay_seconds = other.max_delay_seconds
|
|
1118
|
+
@retry_on = other.retry_on
|
|
1119
|
+
@created_at = other.created_at
|
|
1120
|
+
@updated_at = other.updated_at
|
|
1121
|
+
@deleted_at = other.deleted_at
|
|
1122
|
+
@version = other.version
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1125
|
+
# @api private — Build a {RetryPolicy} from a JSON:API resource returned by
|
|
1126
|
+
# the jobs service, binding it to +client+ so {#save} and {#delete} work.
|
|
1127
|
+
#
|
|
1128
|
+
# @param resource [Object] The JSON:API resource (id + attributes).
|
|
1129
|
+
# @param client [RetryPoliciesClient, nil] Client to bind the policy to.
|
|
1130
|
+
# @return [RetryPolicy] The hydrated policy.
|
|
1131
|
+
def self.from_resource(resource, client: nil)
|
|
1132
|
+
a = resource.attributes
|
|
1133
|
+
new(
|
|
1134
|
+
client,
|
|
1135
|
+
id: resource.id,
|
|
1136
|
+
name: a.name,
|
|
1137
|
+
max_retries: a.max_retries,
|
|
1138
|
+
backoff: a.backoff,
|
|
1139
|
+
delay_seconds: a.delay_seconds,
|
|
1140
|
+
max_delay_seconds: a.max_delay_seconds,
|
|
1141
|
+
retry_on: RetryOn.from_wire(a.retry_on),
|
|
1142
|
+
created_at: a.created_at,
|
|
1143
|
+
updated_at: a.updated_at,
|
|
1144
|
+
deleted_at: a.deleted_at,
|
|
1145
|
+
version: a.version
|
|
1146
|
+
)
|
|
1147
|
+
end
|
|
1148
|
+
end
|
|
860
1149
|
end
|
|
861
1150
|
end
|