smplkit 3.0.119 → 3.0.121

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9911186cf0810c9d76cc16feb24f9a155d8c6708fce3edc406b581b5c9376f1c
4
- data.tar.gz: '009441ca636ade20f9f9a4cbec10d9ea9d2255b81549a2bc7e1274a94091e05d'
3
+ metadata.gz: 6f9ea84a0877be007a56f9f05502329795bb0d8f291cd0df226f2a1b96548980
4
+ data.tar.gz: d93a0cd1b4ae0b03032903a8a64743e8b31fca815a78ecdbc8bca5689be18e64
5
5
  SHA512:
6
- metadata.gz: 5558c39aa882f3bc403613ac51bf20b8f8dddbd4eb663126847a6b5f3a0c5fd961ec13f939c274e3c39c46f3cc2af8d2e44540b999c1e6e4b2239e1a1886e4ec
7
- data.tar.gz: e944872fdef51e90924897ee1173e0dcad70f36255e95a1372f99690f238478852890e54ba1c1a62bbebab2fd7b73f81cecbb4a27591cb79382a348edb46657c
6
+ metadata.gz: 43272f094727b6ecc958a8850582e775a9f0013b0572ff96718c53c26626662692f2f8c4896e1d643b70370bb926214f19cb5c8d714c67c4f9dcabb10cf2d265
7
+ data.tar.gz: 496db856f49fd0950584092683867bfb66f5d0c66eb28c8d3da7d8e8b7ae13f2524483f0a82af348403252123aa6714364b579d77495c9b3aab02721eaa1bdcb
@@ -31,8 +31,17 @@ module SmplkitGeneratedClient::Jobs
31
31
  # The ceiling on the wait between retries, in seconds, for `exponential` backoff — once the doubling reaches it, every subsequent retry waits this long. Only valid with `exponential` backoff; omit it for `fixed`.
32
32
  attr_accessor :max_delay_seconds
33
33
 
34
- # Which failures are retried. A run is retried only when its failure matches this set; an empty set retries nothing. Some failures are never retried regardless of this value.
35
- attr_accessor :retry_on
34
+ # Retry a run that failed because the request did not complete within the job's timeout. Defaults to `false` (timeouts are not retried).
35
+ attr_accessor :retry_on_timeout
36
+
37
+ # Retry a run that failed because the destination could not be reached (DNS, connection refused, TLS, or transport error). Defaults to `false` (connection errors are not retried).
38
+ attr_accessor :retry_on_connection_error
39
+
40
+ # Allowlist of response status patterns to retry when a run fails because the response did not match the job's success status. Each element is either an exact 3-digit HTTP code (e.g. `429`) or a status class (`1xx`, `2xx`, `3xx`, `4xx`, `5xx`) — for example `[\"429\", \"5xx\"]` to retry on rate-limit and any server error. Empty (the default) matches no status, so nothing is retried on a non-success response.
41
+ attr_accessor :retry_statuses
42
+
43
+ # Subtractions from `retry_statuses`, using the same exact-code or class syntax. A status that matches both lists is not retried — `except` wins on overlap — so `retry_statuses` of `[\"5xx\"]` with `retry_statuses_except` of `[\"501\"]` retries every server error except `501`. An element that does not overlap `retry_statuses` is allowed and simply has no effect. Empty (the default) subtracts nothing.
44
+ attr_accessor :retry_statuses_except
36
45
 
37
46
  # When the policy was created.
38
47
  attr_accessor :created_at
@@ -76,7 +85,10 @@ module SmplkitGeneratedClient::Jobs
76
85
  :'backoff' => :'backoff',
77
86
  :'delay_seconds' => :'delay_seconds',
78
87
  :'max_delay_seconds' => :'max_delay_seconds',
79
- :'retry_on' => :'retry_on',
88
+ :'retry_on_timeout' => :'retry_on_timeout',
89
+ :'retry_on_connection_error' => :'retry_on_connection_error',
90
+ :'retry_statuses' => :'retry_statuses',
91
+ :'retry_statuses_except' => :'retry_statuses_except',
80
92
  :'created_at' => :'created_at',
81
93
  :'updated_at' => :'updated_at',
82
94
  :'deleted_at' => :'deleted_at',
@@ -102,7 +114,10 @@ module SmplkitGeneratedClient::Jobs
102
114
  :'backoff' => :'String',
103
115
  :'delay_seconds' => :'Integer',
104
116
  :'max_delay_seconds' => :'Integer',
105
- :'retry_on' => :'RetryOn',
117
+ :'retry_on_timeout' => :'Boolean',
118
+ :'retry_on_connection_error' => :'Boolean',
119
+ :'retry_statuses' => :'Array<String>',
120
+ :'retry_statuses_except' => :'Array<String>',
106
121
  :'created_at' => :'Time',
107
122
  :'updated_at' => :'Time',
108
123
  :'deleted_at' => :'Time',
@@ -165,8 +180,28 @@ module SmplkitGeneratedClient::Jobs
165
180
  self.max_delay_seconds = attributes[:'max_delay_seconds']
166
181
  end
167
182
 
168
- if attributes.key?(:'retry_on')
169
- self.retry_on = attributes[:'retry_on']
183
+ if attributes.key?(:'retry_on_timeout')
184
+ self.retry_on_timeout = attributes[:'retry_on_timeout']
185
+ else
186
+ self.retry_on_timeout = false
187
+ end
188
+
189
+ if attributes.key?(:'retry_on_connection_error')
190
+ self.retry_on_connection_error = attributes[:'retry_on_connection_error']
191
+ else
192
+ self.retry_on_connection_error = false
193
+ end
194
+
195
+ if attributes.key?(:'retry_statuses')
196
+ if (value = attributes[:'retry_statuses']).is_a?(Array)
197
+ self.retry_statuses = value
198
+ end
199
+ end
200
+
201
+ if attributes.key?(:'retry_statuses_except')
202
+ if (value = attributes[:'retry_statuses_except']).is_a?(Array)
203
+ self.retry_statuses_except = value
204
+ end
170
205
  end
171
206
 
172
207
  if attributes.key?(:'created_at')
@@ -333,7 +368,10 @@ module SmplkitGeneratedClient::Jobs
333
368
  backoff == o.backoff &&
334
369
  delay_seconds == o.delay_seconds &&
335
370
  max_delay_seconds == o.max_delay_seconds &&
336
- retry_on == o.retry_on &&
371
+ retry_on_timeout == o.retry_on_timeout &&
372
+ retry_on_connection_error == o.retry_on_connection_error &&
373
+ retry_statuses == o.retry_statuses &&
374
+ retry_statuses_except == o.retry_statuses_except &&
337
375
  created_at == o.created_at &&
338
376
  updated_at == o.updated_at &&
339
377
  deleted_at == o.deleted_at &&
@@ -349,7 +387,7 @@ module SmplkitGeneratedClient::Jobs
349
387
  # Calculates hash code according to all attributes.
350
388
  # @return [Integer] Hash code
351
389
  def hash
352
- [name, max_retries, backoff, delay_seconds, max_delay_seconds, retry_on, created_at, updated_at, deleted_at, version].hash
390
+ [name, max_retries, backoff, delay_seconds, max_delay_seconds, retry_on_timeout, retry_on_connection_error, retry_statuses, retry_statuses_except, created_at, updated_at, deleted_at, version].hash
353
391
  end
354
392
 
355
393
  # Builds the object from hash
@@ -32,7 +32,6 @@ require 'smplkit_jobs_client/models/job_resource'
32
32
  require 'smplkit_jobs_client/models/job_response'
33
33
  require 'smplkit_jobs_client/models/list_meta'
34
34
  require 'smplkit_jobs_client/models/pagination_meta'
35
- require 'smplkit_jobs_client/models/retry_on'
36
35
  require 'smplkit_jobs_client/models/retry_policy'
37
36
  require 'smplkit_jobs_client/models/retry_policy_create_request'
38
37
  require 'smplkit_jobs_client/models/retry_policy_create_resource'
@@ -61,7 +61,25 @@ describe SmplkitGeneratedClient::Jobs::RetryPolicy do
61
61
  end
62
62
  end
63
63
 
64
- describe 'test attribute "retry_on"' do
64
+ describe 'test attribute "retry_on_timeout"' do
65
+ it 'should work' do
66
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
67
+ end
68
+ end
69
+
70
+ describe 'test attribute "retry_on_connection_error"' do
71
+ it 'should work' do
72
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
73
+ end
74
+ end
75
+
76
+ describe 'test attribute "retry_statuses"' do
77
+ it 'should work' do
78
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
79
+ end
80
+ end
81
+
82
+ describe 'test attribute "retry_statuses_except"' do
65
83
  it 'should work' do
66
84
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
67
85
  end
@@ -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,161 @@ 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_timeout [Boolean] Retry a run that timed out. Defaults to
145
+ # +false+.
146
+ # @param retry_on_connection_error [Boolean] Retry a run whose destination
147
+ # could not be reached. Defaults to +false+.
148
+ # @param retry_statuses [Array<String>, nil] Allowlist of response-status
149
+ # patterns to retry on a non-success response. Each element is an exact
150
+ # 3-digit code (e.g. +"429"+) or a class token (+"1xx"+ … +"5xx"+).
151
+ # +nil+ (the default) retries no statuses.
152
+ # @param retry_statuses_except [Array<String>, nil] Patterns subtracted from
153
+ # +retry_statuses+, using the same syntax; +except+ wins on overlap.
154
+ # +nil+ (the default) subtracts nothing.
155
+ # @return [Smplkit::Jobs::RetryPolicy]
156
+ def new(id, name:, max_retries:, backoff:, delay_seconds:, max_delay_seconds: nil,
157
+ retry_on_timeout: false, retry_on_connection_error: false,
158
+ retry_statuses: nil, retry_statuses_except: nil)
159
+ RetryPolicy.new(
160
+ self,
161
+ id: id, name: name, max_retries: max_retries, backoff: backoff,
162
+ delay_seconds: delay_seconds, max_delay_seconds: max_delay_seconds,
163
+ retry_on_timeout: retry_on_timeout,
164
+ retry_on_connection_error: retry_on_connection_error,
165
+ retry_statuses: retry_statuses, retry_statuses_except: retry_statuses_except
166
+ )
167
+ end
168
+
169
+ # List retry policies in the account.
170
+ #
171
+ # @param name [String, nil] Return only policies whose name contains this
172
+ # text (case-insensitive). +nil+ lists all.
173
+ # @param page_number [Integer, nil] 1-based page to return. +nil+ returns
174
+ # the first page.
175
+ # @param page_size [Integer, nil] Maximum number of policies to return in
176
+ # this page. +nil+ uses the server default.
177
+ # @return [Array<Smplkit::Jobs::RetryPolicy>] The policies in this page.
178
+ def list(name: nil, page_number: nil, page_size: nil)
179
+ opts = {}
180
+ opts[:filter_name] = name unless name.nil?
181
+ opts[:page_number] = page_number unless page_number.nil?
182
+ opts[:page_size] = page_size unless page_size.nil?
183
+
184
+ resp = Jobs.call_api { @api.list_retry_policies(opts) }
185
+ (resp.data || []).map { |r| RetryPolicy.from_resource(r, client: self) }
186
+ end
187
+
188
+ # Fetch a single retry policy by its id.
189
+ #
190
+ # @param id [String] Identifier of the policy to fetch.
191
+ # @return [Smplkit::Jobs::RetryPolicy] The matching policy.
192
+ # @raise [Smplkit::NotFoundError] when no policy with this id exists.
193
+ def get(id)
194
+ resp = Jobs.call_api { @api.get_retry_policy(id) }
195
+ RetryPolicy.from_resource(resp.data, client: self)
196
+ end
197
+
198
+ # Delete a retry policy by its id.
199
+ #
200
+ # @param id [String] Identifier of the policy to delete.
201
+ # @return [nil]
202
+ def delete(id)
203
+ Jobs.call_api { @api.delete_retry_policy(id) }
204
+ nil
205
+ end
206
+
207
+ # @api private — POST a new retry policy. Called by {RetryPolicy#save} on
208
+ # unsaved instances. The jobs service requires a caller-supplied
209
+ # +data.id+ on create and 409s on conflict.
210
+ def _create_retry_policy(policy)
211
+ if policy.id.nil? || policy.id.empty?
212
+ raise ArgumentError, "RetryPolicy.id is required on create (caller-supplied key)"
213
+ end
214
+
215
+ resp = Jobs.call_api { @api.create_retry_policy(build_create_body(policy)) }
216
+ RetryPolicy.from_resource(resp.data, client: self)
217
+ end
218
+
219
+ # @api private — Full-replace PUT for an existing retry policy. Called by
220
+ # {RetryPolicy#save} on instances with +created_at+.
221
+ def _update_retry_policy(policy)
222
+ raise ArgumentError, "cannot update a RetryPolicy with no id" if policy.id.nil?
223
+
224
+ resp = Jobs.call_api { @api.update_retry_policy(policy.id, build_body(policy)) }
225
+ RetryPolicy.from_resource(resp.data, client: self)
226
+ end
227
+
228
+ private
229
+
230
+ # Build the generated attributes model shared by create and update. The
231
+ # four retry-condition fields are always sent; +max_delay_seconds+ is sent
232
+ # only when present (omitting it leaves the policy uncapped / is invalid for
233
+ # fixed backoff).
234
+ def build_retry_policy_attrs(policy)
235
+ attrs = {
236
+ name: policy.name,
237
+ max_retries: policy.max_retries,
238
+ backoff: policy.backoff,
239
+ delay_seconds: policy.delay_seconds,
240
+ retry_on_timeout: policy.retry_on_timeout,
241
+ retry_on_connection_error: policy.retry_on_connection_error,
242
+ retry_statuses: Array(policy.retry_statuses).map(&:to_s),
243
+ retry_statuses_except: Array(policy.retry_statuses_except).map(&:to_s)
244
+ }
245
+ attrs[:max_delay_seconds] = policy.max_delay_seconds unless policy.max_delay_seconds.nil?
246
+ SmplkitGeneratedClient::Jobs::RetryPolicy.new(attrs)
247
+ end
248
+
249
+ def build_create_body(policy)
250
+ # Create uses the distinct RetryPolicyCreateRequest envelope; the jobs
251
+ # service requires data.id (the caller-supplied key) on create.
252
+ resource = SmplkitGeneratedClient::Jobs::RetryPolicyCreateResource.new(
253
+ id: policy.id.to_s, type: "retry_policy", attributes: build_retry_policy_attrs(policy)
254
+ )
255
+ SmplkitGeneratedClient::Jobs::RetryPolicyCreateRequest.new(data: resource)
256
+ end
257
+
258
+ def build_body(policy)
259
+ # Update path uses the generic RetryPolicyRequest envelope.
260
+ resource = SmplkitGeneratedClient::Jobs::RetryPolicyResource.new(
261
+ id: policy.id.to_s, type: "retry_policy", attributes: build_retry_policy_attrs(policy)
262
+ )
263
+ SmplkitGeneratedClient::Jobs::RetryPolicyRequest.new(data: resource)
264
+ end
265
+ end
266
+
97
267
  # The Smpl Jobs client — accessed via +client.jobs+.
98
268
  #
99
269
  # Unlike Config/Flags/Logging, Jobs has no live "phone-home" agent — no
@@ -103,8 +273,10 @@ module Smplkit
103
273
  #
104
274
  # client.jobs.{new_recurring_job,new_manual_job,schedule,get,list,delete,run,usage}
105
275
  # client.jobs.runs.{list,get,cancel,rerun}
276
+ # client.jobs.retry_policies.{new,list,get,delete}
106
277
  # Job#{save,delete,trigger,list_runs}
107
278
  # Run#{rerun,cancel}
279
+ # RetryPolicy#{save,delete}
108
280
  #
109
281
  # Build a standalone Smpl Jobs transport from resolved config.
110
282
  #
@@ -139,6 +311,10 @@ module Smplkit
139
311
  # @return [RunsClient] Run history and run actions (+client.jobs.runs+).
140
312
  attr_reader :runs
141
313
 
314
+ # @return [RetryPoliciesClient] Reusable retry policies
315
+ # (+client.jobs.retry_policies+).
316
+ attr_reader :retry_policies
317
+
142
318
  # @param api_key [String, nil] API key. When omitted, resolved from
143
319
  # +SMPLKIT_API_KEY+ or +~/.smplkit+.
144
320
  # @param profile [String, nil] Named +~/.smplkit+ profile section.
@@ -164,6 +340,7 @@ module Smplkit
164
340
  @environment = environment
165
341
  @api = SmplkitGeneratedClient::Jobs::JobsApi.new(auth)
166
342
  @runs = RunsClient.new(SmplkitGeneratedClient::Jobs::RunsApi.new(auth), environment: environment)
343
+ @retry_policies = RetryPoliciesClient.new(SmplkitGeneratedClient::Jobs::RetryPoliciesApi.new(auth))
167
344
  @usage_api = SmplkitGeneratedClient::Jobs::UsageApi.new(auth)
168
345
  end
169
346
 
@@ -191,8 +368,14 @@ module Smplkit
191
368
  # live job already uses this id.
192
369
  # @param name [String] Human-readable name for the job.
193
370
  # @param schedule [String] The base cadence — a 5-field cron expression
194
- # evaluated in UTC (e.g. +"0 2 * * *"+) that every environment inherits
195
- # unless it sets its own override.
371
+ # evaluated in the job's +timezone+ (UTC by default), e.g. +"0 2 * * *"+ —
372
+ # that every environment inherits unless it sets its own override.
373
+ # @param timezone [String, nil] Base IANA timezone the cron +schedule+ is
374
+ # evaluated in (e.g. +"America/New_York"+), DST-aware. +nil+ (the default)
375
+ # means UTC. Every environment inherits it unless it overrides it.
376
+ # @param retry_policy [String, nil] Base retry policy for failed runs — the
377
+ # id of a {Smplkit::Jobs::RetryPolicy}, overridable per environment. +nil+
378
+ # (the default) uses the built-in +"Default"+ policy, which never retries.
196
379
  # @param configuration [Smplkit::Jobs::HttpConfig] The HTTP request the job
197
380
  # sends each time it fires.
198
381
  # @param description [String, nil] Optional free-text description.
@@ -205,11 +388,11 @@ module Smplkit
205
388
  # @param concurrency_policy [String] How overlapping runs are handled.
206
389
  # Defaults to +"ALLOW"+.
207
390
  # @return [Smplkit::Jobs::Job]
208
- def new_recurring_job(id, name:, schedule:, configuration:, description: nil,
209
- environments: nil, concurrency_policy: "ALLOW")
391
+ def new_recurring_job(id, name:, schedule:, configuration:, timezone: nil, retry_policy: nil,
392
+ description: nil, environments: nil, concurrency_policy: "ALLOW")
210
393
  _new_job(
211
- id, name: name, schedule: schedule, configuration: configuration,
212
- description: description, environments: environments,
394
+ id, name: name, schedule: schedule, timezone: timezone, retry_policy: retry_policy,
395
+ configuration: configuration, description: description, environments: environments,
213
396
  concurrency_policy: concurrency_policy, environment: nil
214
397
  )
215
398
  end
@@ -234,12 +417,15 @@ module Smplkit
234
417
  # override). The job is triggerable only in environments enabled here.
235
418
  # @param concurrency_policy [String] How overlapping runs are handled.
236
419
  # Defaults to +"ALLOW"+.
420
+ # @param retry_policy [String, nil] Retry policy for failed runs — the id of
421
+ # a {Smplkit::Jobs::RetryPolicy}, overridable per environment. +nil+ (the
422
+ # default) uses the built-in +"Default"+ policy, which never retries.
237
423
  # @return [Smplkit::Jobs::Job]
238
424
  def new_manual_job(id, name:, configuration:, description: nil,
239
- environments: nil, concurrency_policy: "ALLOW")
425
+ environments: nil, concurrency_policy: "ALLOW", retry_policy: nil)
240
426
  _new_job(
241
- id, name: name, schedule: nil, configuration: configuration,
242
- description: description, environments: environments,
427
+ id, name: name, schedule: nil, retry_policy: retry_policy,
428
+ configuration: configuration, description: description, environments: environments,
243
429
  concurrency_policy: concurrency_policy, environment: nil
244
430
  )
245
431
  end
@@ -259,14 +445,17 @@ module Smplkit
259
445
  # @param description [String, nil] Optional free-text description.
260
446
  # @param concurrency_policy [String] How overlapping runs are handled.
261
447
  # Defaults to +"ALLOW"+.
448
+ # @param retry_policy [String, nil] Retry policy for failed runs — the id of
449
+ # a {Smplkit::Jobs::RetryPolicy}. +nil+ (the default) uses the built-in
450
+ # +"Default"+ policy, which never retries.
262
451
  # @param environment [String, nil] The environment the job is born in.
263
452
  # Defaults to the client's configured environment.
264
453
  # @return [Smplkit::Jobs::Job]
265
454
  def schedule(id, name:, schedule:, configuration:, description: nil,
266
- concurrency_policy: "ALLOW", environment: nil)
455
+ concurrency_policy: "ALLOW", retry_policy: nil, environment: nil)
267
456
  _new_job(
268
- id, name: name, schedule: schedule.iso8601, configuration: configuration,
269
- description: description, environments: nil,
457
+ id, name: name, schedule: schedule.iso8601, retry_policy: retry_policy,
458
+ configuration: configuration, description: description, environments: nil,
270
459
  concurrency_policy: concurrency_policy, environment: environment
271
460
  )
272
461
  end
@@ -377,12 +566,15 @@ module Smplkit
377
566
  # public constructors ({#new_recurring_job}, {#new_manual_job}, {#schedule})
378
567
  # funnel through here.
379
568
  def _new_job(id, name:, schedule:, configuration:, description:,
380
- environments:, concurrency_policy:, environment:)
569
+ environments:, concurrency_policy:, environment:,
570
+ timezone: nil, retry_policy: nil)
381
571
  Job.new(
382
572
  self,
383
573
  id: id,
384
574
  name: name,
385
575
  schedule: schedule,
576
+ timezone: timezone,
577
+ retry_policy: retry_policy,
386
578
  configuration: configuration,
387
579
  description: description,
388
580
  environments: Jobs.normalize_environments(environments),
@@ -394,15 +586,17 @@ module Smplkit
394
586
  # Convert the wrapper +environments+ map to the generated model hash.
395
587
  #
396
588
  # Each entry's +enabled+ is always written; a per-environment +schedule+
397
- # (cron) override, +timezone+ override, and +configuration+ override are
398
- # each sent only when present (omit to inherit the job's base +schedule+ /
399
- # +timezone+ / +configuration+). The read-only per-environment
400
- # +next_run_at+ is never written.
589
+ # (cron) override, +timezone+ override, +retry_policy+ override, and
590
+ # +configuration+ override are each sent only when present (omit to inherit
591
+ # the job's base +schedule+ / +timezone+ / +retry_policy+ /
592
+ # +configuration+). The read-only per-environment +next_run_at+ is never
593
+ # written.
401
594
  def environments_to_wire(environments)
402
595
  (environments || {}).each_with_object({}) do |(env_key, env), out|
403
596
  attrs = { enabled: env.enabled }
404
597
  attrs[:schedule] = env.schedule unless env.schedule.nil?
405
598
  attrs[:timezone] = env.timezone unless env.timezone.nil?
599
+ attrs[:retry_policy] = env.retry_policy unless env.retry_policy.nil?
406
600
  attrs[:configuration] = HttpConfig.to_wire(env.configuration) unless env.configuration.nil?
407
601
  out[env_key.to_s] = SmplkitGeneratedClient::Jobs::JobEnvironment.new(attrs)
408
602
  end
@@ -425,6 +619,9 @@ module Smplkit
425
619
  # explicit +null+ creates a manual job, omitting +timezone+ simply
426
620
  # inherits UTC — so it is sent only when present.)
427
621
  attrs[:timezone] = job.timezone unless job.timezone.nil?
622
+ # +retry_policy+ id; an unset +nil+ is omitted, leaving the server
623
+ # default (the built-in +Default+ policy, which never retries).
624
+ attrs[:retry_policy] = job.retry_policy unless job.retry_policy.nil?
428
625
  environments = job.environments
429
626
  attrs[:environments] = environments_to_wire(environments) unless environments.nil? || environments.empty?
430
627
  SmplkitGeneratedClient::Jobs::Job.new(attrs)
@@ -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 and +timezone+ overrides pass
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,27 @@ 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
130
145
  end
131
146
 
132
147
  # HTTP verb a job uses when it fires.
@@ -300,6 +315,10 @@ module Smplkit
300
315
  # present, it must be a valid IANA zone key (e.g. +"America/New_York"+);
301
316
  # it may be set on an environment that inherits the base schedule (it
302
317
  # need not also override {#schedule}). Sent on writes only when present.
318
+ # @!attribute [rw] retry_policy
319
+ # @return [String, nil] Optional per-environment retry-policy override — the
320
+ # id of a {RetryPolicy} (or +"Default"+). +nil+ (the default) inherits the
321
+ # job's base {Job#retry_policy}. Sent on writes only when present.
303
322
  # @!attribute [rw] configuration
304
323
  # @return [HttpConfig, nil] Optional per-environment request configuration
305
324
  # that fully replaces the job's base {Job#configuration} for this
@@ -310,8 +329,11 @@ module Smplkit
310
329
  # @return [String, nil] Read-only. The next scheduled fire time in this
311
330
  # environment. +nil+ when the environment is not enabled, or once a
312
331
  # one-off run has fired. Never written back on save.
313
- JobEnvironment = Struct.new(:enabled, :schedule, :timezone, :configuration, :next_run_at, keyword_init: true) do
314
- def initialize(enabled: false, schedule: nil, timezone: nil, configuration: nil, next_run_at: nil)
332
+ JobEnvironment = Struct.new(
333
+ :enabled, :schedule, :timezone, :retry_policy, :configuration, :next_run_at, keyword_init: true
334
+ ) do
335
+ def initialize(enabled: false, schedule: nil, timezone: nil, retry_policy: nil,
336
+ configuration: nil, next_run_at: nil)
315
337
  super
316
338
  end
317
339
 
@@ -328,6 +350,7 @@ module Smplkit
328
350
  enabled: src.enabled.nil? ? false : src.enabled,
329
351
  schedule: src.schedule,
330
352
  timezone: src.timezone,
353
+ retry_policy: src.retry_policy,
331
354
  configuration: cfg.nil? ? nil : HttpConfig.from_wire(cfg),
332
355
  next_run_at: src.next_run_at
333
356
  )
@@ -406,6 +429,13 @@ module Smplkit
406
429
  # present.
407
430
  attr_accessor :timezone
408
431
 
432
+ # @return [String, nil] The base retry policy for failed runs — the id of a
433
+ # {RetryPolicy}, overridable per environment via
434
+ # {JobEnvironment#retry_policy}. +nil+ (the default, omitted on the wire)
435
+ # uses the built-in +"Default"+ policy, which never retries. Set it with
436
+ # {#set_retry_policy}; sent on writes only when present.
437
+ attr_accessor :retry_policy
438
+
409
439
  # @return [HttpConfig] The base HTTP request to perform when the job fires.
410
440
  # Per-environment overrides live in {#environments}.
411
441
  attr_accessor :configuration
@@ -436,7 +466,7 @@ module Smplkit
436
466
  attr_accessor :birth_environment
437
467
 
438
468
  def initialize(client = nil, id:, name:, configuration:, schedule: nil,
439
- timezone: nil, description: nil, environments: nil,
469
+ timezone: nil, retry_policy: nil, description: nil, environments: nil,
440
470
  kind: nil, type: "http", concurrency_policy: "ALLOW",
441
471
  birth_environment: nil, created_at: nil,
442
472
  updated_at: nil, deleted_at: nil, version: nil)
@@ -449,6 +479,7 @@ module Smplkit
449
479
  @type = type
450
480
  @schedule = schedule
451
481
  @timezone = timezone
482
+ @retry_policy = retry_policy
452
483
  @configuration = configuration
453
484
  @concurrency_policy = concurrency_policy
454
485
  @birth_environment = birth_environment
@@ -588,17 +619,27 @@ module Smplkit
588
619
  # the cadence within that environment; it cannot turn a one-off job
589
620
  # recurring or vice-versa. Call {#save} to persist.
590
621
  #
622
+ # Because the timezone is an integral part of a cron cadence, a +timezone+
623
+ # may be supplied alongside the schedule; when given it sets the same
624
+ # scope's timezone too (equivalent to a follow-up {#set_timezone}). Omit it
625
+ # to leave the timezone untouched. For a timezone-only change, use
626
+ # {#set_timezone}.
627
+ #
591
628
  # @param schedule [String] An ISO-8601 datetime, a 5-field UTC cron
592
629
  # expression, or the literal +"now"+ (base); a 5-field UTC cron
593
630
  # expression (per-environment).
631
+ # @param timezone [String, nil] An optional IANA timezone to set on the
632
+ # same scope (recurring jobs only). +nil+ (the default) leaves the
633
+ # timezone untouched.
594
634
  # @param environment [String, nil] An environment key for a per-environment
595
635
  # override, or +nil+ to set the base schedule.
596
- def set_schedule(schedule, environment: nil)
636
+ def set_schedule(schedule, timezone: nil, environment: nil)
597
637
  if environment.nil?
598
638
  @schedule = schedule
599
639
  else
600
640
  _environment_override(environment).schedule = schedule
601
641
  end
642
+ set_timezone(timezone, environment: environment) unless timezone.nil?
602
643
  end
603
644
 
604
645
  # Set the IANA timezone the cron schedule is evaluated in — base
@@ -624,6 +665,31 @@ module Smplkit
624
665
  end
625
666
  end
626
667
 
668
+ # Set the retry policy for failed runs — base (+environment+ omitted) or
669
+ # per-environment.
670
+ #
671
+ # With +environment+ omitted (the default), sets the base {#retry_policy}
672
+ # every environment inherits unless it overrides it. With an +environment+
673
+ # given, sets that environment's per-environment override on
674
+ # {#environments}, creating the override entry if it doesn't exist yet
675
+ # (preserving any already-set +enabled+ / +schedule+ / +timezone+ /
676
+ # +configuration+ on it). Call {#save} to persist.
677
+ #
678
+ # Accepts either a {RetryPolicy} instance (its id is used) or a policy id
679
+ # string — pass +"Default"+ for the built-in never-retry policy.
680
+ #
681
+ # @param retry_policy [RetryPolicy, String] A {RetryPolicy} or a policy id.
682
+ # @param environment [String, nil] An environment key for a per-environment
683
+ # override, or +nil+ to set the base retry policy.
684
+ def set_retry_policy(retry_policy, environment: nil)
685
+ policy_id = retry_policy.is_a?(RetryPolicy) ? retry_policy.id : retry_policy
686
+ if environment.nil?
687
+ @retry_policy = policy_id
688
+ else
689
+ _environment_override(environment).retry_policy = policy_id
690
+ end
691
+ end
692
+
627
693
  # Trigger one immediate, manual run of this job (a +MANUAL+ run).
628
694
  #
629
695
  # @param environment [String, nil] Environment the run executes in.
@@ -641,17 +707,25 @@ module Smplkit
641
707
  #
642
708
  # @param environment [String, nil] Restrict to runs stamped with this
643
709
  # environment. +nil+ covers every environment you can access.
710
+ # @param triggers [Array<String>, nil] Restrict to runs started by any of
711
+ # these triggers (see {RunTrigger}) — e.g. +[RunTrigger::RETRY]+ for
712
+ # automatic retries. +nil+ covers every trigger.
713
+ # @param last_run_only [Boolean] When +true+, return only the last
714
+ # completed run per environment (in-flight runs excluded). Defaults to
715
+ # +false+.
644
716
  # @param page_size [Integer, nil] Maximum number of runs to return in this
645
717
  # page.
646
718
  # @param after [String, nil] Opaque cursor from a previous page.
647
719
  # @return [Array<Smplkit::Jobs::Run>] The runs in this page.
648
720
  # @raise [RuntimeError] when this job has no bound client.
649
- def list_runs(environment: nil, page_size: nil, after: nil)
721
+ def list_runs(environment: nil, triggers: nil, last_run_only: false, page_size: nil, after: nil)
650
722
  raise "Job was constructed without a client; cannot list runs" if @client.nil?
651
723
 
652
724
  @client.runs.list(
653
725
  job: @id,
654
726
  environments: environment.nil? ? nil : [environment],
727
+ triggers: triggers,
728
+ last_run_only: last_run_only,
655
729
  page_size: page_size,
656
730
  after: after
657
731
  )
@@ -678,6 +752,7 @@ module Smplkit
678
752
  @type = other.type
679
753
  @schedule = other.schedule
680
754
  @timezone = other.timezone
755
+ @retry_policy = other.retry_policy
681
756
  @configuration = other.configuration
682
757
  @concurrency_policy = other.concurrency_policy
683
758
  @created_at = other.created_at
@@ -709,6 +784,7 @@ module Smplkit
709
784
  type: a.type || "http",
710
785
  schedule: a.schedule,
711
786
  timezone: a.timezone,
787
+ retry_policy: a.retry_policy,
712
788
  configuration: HttpConfig.from_wire(a.configuration),
713
789
  concurrency_policy: a.concurrency_policy || "ALLOW",
714
790
  created_at: a.created_at,
@@ -719,6 +795,16 @@ module Smplkit
719
795
  end
720
796
  end
721
797
 
798
+ # Where a +RETRY+ run sits in its retry chain (read-only).
799
+ #
800
+ # @!attribute [rw] of
801
+ # @return [String] Id of the chain's original run — the first attempt that
802
+ # failed and started the chain.
803
+ # @!attribute [rw] attempt
804
+ # @return [Integer] Which retry this run is — +1+ for the first retry, +2+
805
+ # for the second, and so on.
806
+ RunRetry = Struct.new(:of, :attempt, keyword_init: true)
807
+
722
808
  # A single execution of a job (read-only) with +rerun+ / +cancel+ actions.
723
809
  #
724
810
  # Runs are created and mutated by the jobs service, not by clients; clients
@@ -741,6 +827,9 @@ module Smplkit
741
827
  # {RunTrigger} constants: +SCHEDULE+, +MANUAL+ (run now), or +RERUN+.
742
828
  # @!attribute [rw] rerun_of
743
829
  # @return [String, nil] The source run's id; set only when +trigger+ is +RERUN+.
830
+ # @!attribute [rw] retry
831
+ # @return [RunRetry, nil] Retry-chain position, populated only when
832
+ # +trigger+ is +RETRY+; +nil+ otherwise.
744
833
  # @!attribute [rw] scheduled_for
745
834
  # @return [String, nil] The intended fire time for a scheduled run; +nil+
746
835
  # for manual / rerun runs.
@@ -767,7 +856,7 @@ module Smplkit
767
856
  # @!attribute [rw] created_at
768
857
  # @return [String, nil] When the run was enqueued (became +PENDING+).
769
858
  Run = Struct.new(
770
- :id, :job, :job_version, :environment, :trigger, :rerun_of, :scheduled_for,
859
+ :id, :job, :job_version, :environment, :trigger, :rerun_of, :retry, :scheduled_for,
771
860
  :status, :started_at, :finished_at, :pending_duration_ms, :run_duration_ms,
772
861
  :total_duration_ms, :failure_reason, :error, :request, :result, :created_at,
773
862
  keyword_init: true
@@ -780,6 +869,12 @@ module Smplkit
780
869
  # @return [Run] The hydrated run.
781
870
  def self.from_resource(resource, runs: nil)
782
871
  a = resource.attributes
872
+ # The retry-chain position is populated only on a +RETRY+ run; the
873
+ # generated model exposes it as +_retry+ (+retry+ is a Ruby keyword).
874
+ retry_chain = a._retry
875
+ retry_pos = if a.trigger == RunTrigger::RETRY && !retry_chain.nil?
876
+ RunRetry.new(of: retry_chain.of, attempt: retry_chain.attempt)
877
+ end
783
878
  new(
784
879
  id: resource.id,
785
880
  job: a.job,
@@ -787,6 +882,7 @@ module Smplkit
787
882
  environment: a.environment,
788
883
  trigger: a.trigger,
789
884
  rerun_of: a.rerun_of,
885
+ retry: retry_pos,
790
886
  scheduled_for: a.scheduled_for,
791
887
  status: a.status,
792
888
  started_at: a.started_at,
@@ -857,5 +953,170 @@ module Smplkit
857
953
  )
858
954
  end
859
955
  end
956
+
957
+ # A named, reusable automatic-retry policy.
958
+ #
959
+ # Active-record style: instantiate via +client.jobs.retry_policies.new(...)+,
960
+ # mutate fields directly, and call {#save} to persist or {#delete} to remove.
961
+ # Reference a saved policy from a job's {Job#retry_policy} (see
962
+ # {JobsClient#new_recurring_job} and {Job#set_retry_policy}). Retry policies
963
+ # are account-global — never environment-scoped.
964
+ #
965
+ # A policy decides whether and how a failed run is retried. A job that
966
+ # references nothing uses the built-in +"Default"+ policy, which never
967
+ # retries.
968
+ class RetryPolicy
969
+ # @return [String] Caller-supplied unique identifier for the policy (the
970
+ # resource +id+). Unique within the account and immutable; the service
971
+ # returns 409 if another live policy already uses this id.
972
+ attr_accessor :id
973
+
974
+ # @return [String] Human-readable name for the policy.
975
+ attr_accessor :name
976
+
977
+ # @return [Integer] How many times a failed run is retried after the
978
+ # initial attempt — +3+ means up to 4 attempts total. +0+ disables
979
+ # retries. Maximum 10.
980
+ attr_accessor :max_retries
981
+
982
+ # @return [String] How the wait between retries grows; one of {Backoff}.
983
+ attr_accessor :backoff
984
+
985
+ # @return [Integer] The wait before a retry, in seconds — the constant wait
986
+ # for {Backoff::FIXED}, or the base that doubles each retry for
987
+ # {Backoff::EXPONENTIAL}.
988
+ attr_accessor :delay_seconds
989
+
990
+ # @return [Integer, nil] Ceiling on the wait between retries, for
991
+ # {Backoff::EXPONENTIAL} backoff only. +nil+ (the default, omitted on the
992
+ # wire) leaves it uncapped; omit it for {Backoff::FIXED}.
993
+ attr_accessor :max_delay_seconds
994
+
995
+ # @return [Boolean] Retry a run that timed out. Defaults to +false+.
996
+ attr_accessor :retry_on_timeout
997
+
998
+ # @return [Boolean] Retry a run whose destination could not be reached (a
999
+ # connection error). Defaults to +false+.
1000
+ attr_accessor :retry_on_connection_error
1001
+
1002
+ # @return [Array<String>] Allowlist of response-status patterns to retry on
1003
+ # a non-success response. Each element is an exact 3-digit code (e.g.
1004
+ # +"429"+) or a class token (+"1xx"+ … +"5xx"+). Defaults to an empty
1005
+ # list (retries no statuses).
1006
+ attr_accessor :retry_statuses
1007
+
1008
+ # @return [Array<String>] Patterns subtracted from {#retry_statuses}, using
1009
+ # the same exact-code or class syntax. A status matching both lists is not
1010
+ # retried — +except+ wins on overlap. Defaults to an empty list.
1011
+ attr_accessor :retry_statuses_except
1012
+
1013
+ # @return [String, nil] ISO-8601 timestamp of first persist. +nil+ for an
1014
+ # unsaved instance.
1015
+ attr_accessor :created_at
1016
+
1017
+ # @return [String, nil] ISO-8601 timestamp of the most recent mutation.
1018
+ attr_accessor :updated_at
1019
+
1020
+ # @return [String, nil] Timestamp when the policy was deleted; +nil+ for
1021
+ # live policies.
1022
+ attr_accessor :deleted_at
1023
+
1024
+ # @return [Integer, nil] Monotonic version counter, bumped on every
1025
+ # server-side write.
1026
+ attr_accessor :version
1027
+
1028
+ def initialize(client = nil, id:, name:, max_retries:, backoff:, delay_seconds:,
1029
+ max_delay_seconds: nil, retry_on_timeout: false,
1030
+ retry_on_connection_error: false, retry_statuses: nil,
1031
+ retry_statuses_except: nil, created_at: nil,
1032
+ updated_at: nil, deleted_at: nil, version: nil)
1033
+ @client = client
1034
+ @id = id
1035
+ @name = name
1036
+ @max_retries = max_retries
1037
+ @backoff = backoff
1038
+ @delay_seconds = delay_seconds
1039
+ @max_delay_seconds = max_delay_seconds
1040
+ @retry_on_timeout = retry_on_timeout
1041
+ @retry_on_connection_error = retry_on_connection_error
1042
+ @retry_statuses = retry_statuses || []
1043
+ @retry_statuses_except = retry_statuses_except || []
1044
+ @created_at = created_at
1045
+ @updated_at = updated_at
1046
+ @deleted_at = deleted_at
1047
+ @version = version
1048
+ end
1049
+
1050
+ # Create this policy, or full-replace it if it already exists.
1051
+ #
1052
+ # Upsert behavior is driven by {#created_at}: a policy with no +created_at+
1053
+ # is created (POST); otherwise it's full-replace updated (PUT). After the
1054
+ # call, every field is refreshed from the server response.
1055
+ #
1056
+ # @return [self]
1057
+ def save
1058
+ raise "RetryPolicy was constructed without a client; cannot save" if @client.nil?
1059
+
1060
+ updated = @created_at.nil? ? @client._create_retry_policy(self) : @client._update_retry_policy(self)
1061
+ _apply(updated)
1062
+ self
1063
+ end
1064
+ alias save! save
1065
+
1066
+ # Delete this policy on the server.
1067
+ #
1068
+ # @return [nil]
1069
+ def delete
1070
+ raise "RetryPolicy was constructed without a client or id; cannot delete" if @client.nil? || @id.nil?
1071
+
1072
+ @client.delete(@id)
1073
+ end
1074
+ alias delete! delete
1075
+
1076
+ # @api private
1077
+ def _apply(other)
1078
+ @id = other.id
1079
+ @name = other.name
1080
+ @max_retries = other.max_retries
1081
+ @backoff = other.backoff
1082
+ @delay_seconds = other.delay_seconds
1083
+ @max_delay_seconds = other.max_delay_seconds
1084
+ @retry_on_timeout = other.retry_on_timeout
1085
+ @retry_on_connection_error = other.retry_on_connection_error
1086
+ @retry_statuses = other.retry_statuses
1087
+ @retry_statuses_except = other.retry_statuses_except
1088
+ @created_at = other.created_at
1089
+ @updated_at = other.updated_at
1090
+ @deleted_at = other.deleted_at
1091
+ @version = other.version
1092
+ end
1093
+
1094
+ # @api private — Build a {RetryPolicy} from a JSON:API resource returned by
1095
+ # the jobs service, binding it to +client+ so {#save} and {#delete} work.
1096
+ #
1097
+ # @param resource [Object] The JSON:API resource (id + attributes).
1098
+ # @param client [RetryPoliciesClient, nil] Client to bind the policy to.
1099
+ # @return [RetryPolicy] The hydrated policy.
1100
+ def self.from_resource(resource, client: nil)
1101
+ a = resource.attributes
1102
+ new(
1103
+ client,
1104
+ id: resource.id,
1105
+ name: a.name,
1106
+ max_retries: a.max_retries,
1107
+ backoff: a.backoff,
1108
+ delay_seconds: a.delay_seconds,
1109
+ max_delay_seconds: a.max_delay_seconds,
1110
+ retry_on_timeout: a.retry_on_timeout || false,
1111
+ retry_on_connection_error: a.retry_on_connection_error || false,
1112
+ retry_statuses: a.retry_statuses || [],
1113
+ retry_statuses_except: a.retry_statuses_except || [],
1114
+ created_at: a.created_at,
1115
+ updated_at: a.updated_at,
1116
+ deleted_at: a.deleted_at,
1117
+ version: a.version
1118
+ )
1119
+ end
1120
+ end
860
1121
  end
861
1122
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smplkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.119
4
+ version: 3.0.121
5
5
  platform: ruby
6
6
  authors:
7
7
  - Smpl Solutions LLC
@@ -778,7 +778,6 @@ files:
778
778
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/job_response.rb
779
779
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/list_meta.rb
780
780
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/pagination_meta.rb
781
- - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/retry_on.rb
782
781
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/retry_policy.rb
783
782
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/retry_policy_create_request.rb
784
783
  - lib/smplkit/_generated/jobs/lib/smplkit_jobs_client/models/retry_policy_create_resource.rb
@@ -815,7 +814,6 @@ files:
815
814
  - lib/smplkit/_generated/jobs/spec/models/job_spec.rb
816
815
  - lib/smplkit/_generated/jobs/spec/models/list_meta_spec.rb
817
816
  - lib/smplkit/_generated/jobs/spec/models/pagination_meta_spec.rb
818
- - lib/smplkit/_generated/jobs/spec/models/retry_on_spec.rb
819
817
  - lib/smplkit/_generated/jobs/spec/models/retry_policy_create_request_spec.rb
820
818
  - lib/smplkit/_generated/jobs/spec/models/retry_policy_create_resource_spec.rb
821
819
  - lib/smplkit/_generated/jobs/spec/models/retry_policy_list_response_spec.rb
@@ -1,185 +0,0 @@
1
- =begin
2
- #smplkit Jobs API
3
-
4
- #Scheduled HTTP job execution API for smplkit.
5
-
6
- The version of the OpenAPI document: 0.1.0
7
-
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.22.0
10
-
11
- =end
12
-
13
- require 'date'
14
- require 'time'
15
-
16
- module SmplkitGeneratedClient::Jobs
17
- # Which failures a policy retries. An empty policy (both lists empty or absent) retries nothing.
18
- class RetryOn < ApiModelBase
19
- # Response status codes that should be retried when a run fails because the response did not match the job's success status (for example `[429, 503]` to retry on rate-limit and unavailable). Each is a 3-digit HTTP status code. Empty matches no status.
20
- attr_accessor :statuses
21
-
22
- # Failure reasons that should be retried: `TIMEOUT` (the run did not complete in time), `CONNECTION_ERROR` (the endpoint could not be reached), or `NON_SUCCESS_STATUS` (any non-success response, regardless of `statuses`). Empty matches no reason.
23
- attr_accessor :reasons
24
-
25
- class EnumAttributeValidator
26
- attr_reader :datatype
27
- attr_reader :allowable_values
28
-
29
- def initialize(datatype, allowable_values)
30
- @allowable_values = allowable_values.map do |value|
31
- case datatype.to_s
32
- when /Integer/i
33
- value.to_i
34
- when /Float/i
35
- value.to_f
36
- else
37
- value
38
- end
39
- end
40
- end
41
-
42
- def valid?(value)
43
- !value || allowable_values.include?(value)
44
- end
45
- end
46
-
47
- # Attribute mapping from ruby-style variable name to JSON key.
48
- def self.attribute_map
49
- {
50
- :'statuses' => :'statuses',
51
- :'reasons' => :'reasons'
52
- }
53
- end
54
-
55
- # Returns attribute mapping this model knows about
56
- def self.acceptable_attribute_map
57
- attribute_map
58
- end
59
-
60
- # Returns all the JSON keys this model knows about
61
- def self.acceptable_attributes
62
- acceptable_attribute_map.values
63
- end
64
-
65
- # Attribute type mapping.
66
- def self.openapi_types
67
- {
68
- :'statuses' => :'Array<Integer>',
69
- :'reasons' => :'Array<String>'
70
- }
71
- end
72
-
73
- # List of attributes with nullable: true
74
- def self.openapi_nullable
75
- Set.new([
76
- ])
77
- end
78
-
79
- # Initializes the object
80
- # @param [Hash] attributes Model attributes in the form of hash
81
- def initialize(attributes = {})
82
- if (!attributes.is_a?(Hash))
83
- fail ArgumentError, "The input argument (attributes) must be a hash in `SmplkitGeneratedClient::Jobs::RetryOn` initialize method"
84
- end
85
-
86
- # check to see if the attribute exists and convert string to symbol for hash key
87
- acceptable_attribute_map = self.class.acceptable_attribute_map
88
- attributes = attributes.each_with_object({}) { |(k, v), h|
89
- if (!acceptable_attribute_map.key?(k.to_sym))
90
- fail ArgumentError, "`#{k}` is not a valid attribute in `SmplkitGeneratedClient::Jobs::RetryOn`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
91
- end
92
- h[k.to_sym] = v
93
- }
94
-
95
- if attributes.key?(:'statuses')
96
- if (value = attributes[:'statuses']).is_a?(Array)
97
- self.statuses = value
98
- end
99
- end
100
-
101
- if attributes.key?(:'reasons')
102
- if (value = attributes[:'reasons']).is_a?(Array)
103
- self.reasons = value
104
- end
105
- end
106
- end
107
-
108
- # Show invalid properties with the reasons. Usually used together with valid?
109
- # @return Array for valid properties with the reasons
110
- def list_invalid_properties
111
- warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
112
- invalid_properties = Array.new
113
- invalid_properties
114
- end
115
-
116
- # Check to see if the all the properties in the model are valid
117
- # @return true if the model is valid
118
- def valid?
119
- warn '[DEPRECATED] the `valid?` method is obsolete'
120
- true
121
- end
122
-
123
- # Checks equality by comparing each attribute.
124
- # @param [Object] Object to be compared
125
- def ==(o)
126
- return true if self.equal?(o)
127
- self.class == o.class &&
128
- statuses == o.statuses &&
129
- reasons == o.reasons
130
- end
131
-
132
- # @see the `==` method
133
- # @param [Object] Object to be compared
134
- def eql?(o)
135
- self == o
136
- end
137
-
138
- # Calculates hash code according to all attributes.
139
- # @return [Integer] Hash code
140
- def hash
141
- [statuses, reasons].hash
142
- end
143
-
144
- # Builds the object from hash
145
- # @param [Hash] attributes Model attributes in the form of hash
146
- # @return [Object] Returns the model itself
147
- def self.build_from_hash(attributes)
148
- return nil unless attributes.is_a?(Hash)
149
- attributes = attributes.transform_keys(&:to_sym)
150
- transformed_hash = {}
151
- openapi_types.each_pair do |key, type|
152
- if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
153
- transformed_hash["#{key}"] = nil
154
- elsif type =~ /\AArray<(.*)>/i
155
- # check to ensure the input is an array given that the attribute
156
- # is documented as an array but the input is not
157
- if attributes[attribute_map[key]].is_a?(Array)
158
- transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
159
- end
160
- elsif !attributes[attribute_map[key]].nil?
161
- transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
162
- end
163
- end
164
- new(transformed_hash)
165
- end
166
-
167
- # Returns the object in the form of hash
168
- # @return [Hash] Returns the object in the form of hash
169
- def to_hash
170
- hash = {}
171
- self.class.attribute_map.each_pair do |attr, param|
172
- value = self.send(attr)
173
- if value.nil?
174
- is_nullable = self.class.openapi_nullable.include?(attr)
175
- next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
176
- end
177
-
178
- hash[param] = _to_hash(value)
179
- end
180
- hash
181
- end
182
-
183
- end
184
-
185
- end
@@ -1,46 +0,0 @@
1
- =begin
2
- #smplkit Jobs API
3
-
4
- #Scheduled HTTP job execution API for smplkit.
5
-
6
- The version of the OpenAPI document: 0.1.0
7
-
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.22.0
10
-
11
- =end
12
-
13
- require 'spec_helper'
14
- require 'json'
15
- require 'date'
16
-
17
- # Unit tests for SmplkitGeneratedClient::Jobs::RetryOn
18
- # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
- # Please update as you see appropriate
20
- describe SmplkitGeneratedClient::Jobs::RetryOn do
21
- #let(:instance) { SmplkitGeneratedClient::Jobs::RetryOn.new }
22
-
23
- describe 'test an instance of RetryOn' do
24
- it 'should create an instance of RetryOn' do
25
- # uncomment below to test the instance creation
26
- #expect(instance).to be_instance_of(SmplkitGeneratedClient::Jobs::RetryOn)
27
- end
28
- end
29
-
30
- describe 'test attribute "statuses"' do
31
- it 'should work' do
32
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
- end
34
- end
35
-
36
- describe 'test attribute "reasons"' do
37
- it 'should work' do
38
- # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
- # validator = Petstore::EnumTest::EnumAttributeValidator.new('Array<String>', ["TIMEOUT", "CONNECTION_ERROR", "NON_SUCCESS_STATUS"])
40
- # validator.allowable_values.each do |value|
41
- # expect { instance.reasons = value }.not_to raise_error
42
- # end
43
- end
44
- end
45
-
46
- end