smplkit 3.0.118 → 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.
@@ -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 (e.g. +"0 2 * * *"+) that every environment inherits
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:, description: nil,
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, configuration: configuration,
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, configuration: configuration,
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, configuration: configuration,
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, 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.
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)