Class: Smplkit::Jobs::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/smplkit/jobs/models.rb

Overview

A unit of work: an HTTP request, run on a schedule or triggered on demand.

Active-record style: instantiate via client.jobs.new_recurring_job(…), new_manual_job(…), or schedule(…), mutate fields directly, and call #save to persist or #delete to remove. Header values in configuration.headers are returned in plaintext on reads, so fetching a job, mutating it, and calling #save preserves its header values without re-entering secrets.

A job’s #kind follows from its #schedule: a recurring (cron) job, a manual job (no schedule, runs only when triggered), or a one-off (now / datetime) job that runs a single time. Enablement is per environment, set via #set_enabled (and read via #is_enabled); base #enabled is a derived roll-up over #environments. The base schedule is environment-agnostic, while each environment may carry its own cron #set_schedule override.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client = nil, id:, name:, configuration:, schedule: nil, timezone: nil, retry_policy: nil, description: nil, environments: nil, kind: nil, type: "http", concurrency_policy: "ALLOW", birth_environment: nil, created_at: nil, updated_at: nil, deleted_at: nil, version: nil) ⇒ Job

Returns a new instance of Job.



468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
# File 'lib/smplkit/jobs/models.rb', line 468

def initialize(client = nil, id:, name:, configuration:, schedule: nil,
               timezone: nil, retry_policy: nil, description: nil, environments: nil,
               kind: nil, type: "http", concurrency_policy: "ALLOW",
               birth_environment: nil, created_at: nil,
               updated_at: nil, deleted_at: nil, version: nil)
  @client = client
  @id = id
  @name = name
  @description = description
  @environments = environments || {}
  @kind = kind
  @type = type
  @schedule = schedule
  @timezone = timezone
  @retry_policy = retry_policy
  @configuration = configuration
  @concurrency_policy = concurrency_policy
  @birth_environment = birth_environment
  @created_at = created_at
  @updated_at = updated_at
  @deleted_at = deleted_at
  @version = version
end

Instance Attribute Details

#birth_environmentObject



466
467
468
# File 'lib/smplkit/jobs/models.rb', line 466

def birth_environment
  @birth_environment
end

#concurrency_policyString

Returns How overlapping runs are handled. “ALLOW” (the only value) permits them.

Returns:

  • (String)

    How overlapping runs are handled. “ALLOW” (the only value) permits them.



445
446
447
# File 'lib/smplkit/jobs/models.rb', line 445

def concurrency_policy
  @concurrency_policy
end

#configurationHttpConfig

Returns The base HTTP request to perform when the job fires. Per-environment overrides live in #environments.

Returns:

  • (HttpConfig)

    The base HTTP request to perform when the job fires. Per-environment overrides live in #environments.



441
442
443
# File 'lib/smplkit/jobs/models.rb', line 441

def configuration
  @configuration
end

#created_atString?

Returns ISO-8601 timestamp of first persist. nil for an unsaved instance.

Returns:

  • (String, nil)

    ISO-8601 timestamp of first persist. nil for an unsaved instance.



449
450
451
# File 'lib/smplkit/jobs/models.rb', line 449

def created_at
  @created_at
end

#deleted_atString?

Returns Timestamp when the job was deleted; nil for live jobs.

Returns:

  • (String, nil)

    Timestamp when the job was deleted; nil for live jobs.



456
457
458
# File 'lib/smplkit/jobs/models.rb', line 456

def deleted_at
  @deleted_at
end

#descriptionString?

Returns Free-text description. nil when unset.

Returns:

  • (String, nil)

    Free-text description. nil when unset.



386
387
388
# File 'lib/smplkit/jobs/models.rb', line 386

def description
  @description
end

#environmentsHash{String => JobEnvironment}

Returns Per-environment overrides keyed by environment key (e.g. “production”). The writable surface for enablement: a recurring job fires in an environment only when environments[env].enabled is true. Each entry may carry an optional HttpConfig override; omit it to inherit the base #configuration. Every referenced environment must exist and be managed for the account.

Returns:

  • (Hash{String => JobEnvironment})

    Per-environment overrides keyed by environment key (e.g. “production”). The writable surface for enablement: a recurring job fires in an environment only when environments[env].enabled is true. Each entry may carry an optional HttpConfig override; omit it to inherit the base #configuration. Every referenced environment must exist and be managed for the account.



402
403
404
# File 'lib/smplkit/jobs/models.rb', line 402

def environments
  @environments
end

#idString

Caller-supplied unique identifier for the job (the resource id). Unique within the account and immutable; the service returns 409 if another live job already uses this id.

Returns:

  • (String)

    Caller-supplied unique identifier for the job (the resource id). Unique within the account and immutable; the service returns 409 if another live job already uses this id.



380
381
382
# File 'lib/smplkit/jobs/models.rb', line 380

def id
  @id
end

#kindString?

Returns Read-only. How the job runs, derived from its #schedule by the server: one of Smplkit::Jobs::JobKind::RECURRING, Smplkit::Jobs::JobKind::MANUAL, or Smplkit::Jobs::JobKind::ONE_OFF. nil on an unsaved instance.

Returns:



407
408
409
# File 'lib/smplkit/jobs/models.rb', line 407

def kind
  @kind
end

#nameString

Returns Human-readable name for the job.

Returns:

  • (String)

    Human-readable name for the job.



383
384
385
# File 'lib/smplkit/jobs/models.rb', line 383

def name
  @name
end

#retry_policyString?

Returns The base retry policy for failed runs — the id of a RetryPolicy, overridable per environment via Smplkit::Jobs::JobEnvironment#retry_policy. nil (the default, omitted on the wire) uses the built-in “Default” policy, which never retries. Set it with #set_retry_policy; sent on writes only when present.

Returns:



437
438
439
# File 'lib/smplkit/jobs/models.rb', line 437

def retry_policy
  @retry_policy
end

#scheduleString?

Returns The base schedule every environment inherits, and the field that determines the job’s #kind: nil (omitted) for a permanent manual job that never auto-fires; a 5-field cron expression evaluated in UTC for a recurring job; an ISO-8601 datetime for a one-off run at that instant; or the literal “now” for a one-off run as soon as possible. A datetime or “now” job disables itself after it fires. The schedule is environment-agnostic — set it with #set_schedule.

Returns:

  • (String, nil)

    The base schedule every environment inherits, and the field that determines the job’s #kind: nil (omitted) for a permanent manual job that never auto-fires; a 5-field cron expression evaluated in UTC for a recurring job; an ISO-8601 datetime for a one-off run at that instant; or the literal “now” for a one-off run as soon as possible. A datetime or “now” job disables itself after it fires. The schedule is environment-agnostic — set it with #set_schedule.



420
421
422
# File 'lib/smplkit/jobs/models.rb', line 420

def schedule
  @schedule
end

#timezoneString?

Returns The base IANA timezone the cron #schedule is evaluated in (e.g. “America/New_York”); nil (the default) means UTC. The base every environment inherits unless it sets its own Smplkit::Jobs::JobEnvironment#timezone. The cron fires on this zone’s wall clock (DST-aware) while next_run_at is still reported as a UTC instant. Only valid on a recurring (cron) job — leave nil for a manual or one-off job. Set it with #set_timezone; sent on writes only when present.

Returns:

  • (String, nil)

    The base IANA timezone the cron #schedule is evaluated in (e.g. “America/New_York”); nil (the default) means UTC. The base every environment inherits unless it sets its own Smplkit::Jobs::JobEnvironment#timezone. The cron fires on this zone’s wall clock (DST-aware) while next_run_at is still reported as a UTC instant. Only valid on a recurring (cron) job — leave nil for a manual or one-off job. Set it with #set_timezone; sent on writes only when present.



430
431
432
# File 'lib/smplkit/jobs/models.rb', line 430

def timezone
  @timezone
end

#typeString

Returns Job type. Only “http” is supported today.

Returns:

  • (String)

    Job type. Only “http” is supported today.



410
411
412
# File 'lib/smplkit/jobs/models.rb', line 410

def type
  @type
end

#updated_atString?

Returns ISO-8601 timestamp of the most recent mutation.

Returns:

  • (String, nil)

    ISO-8601 timestamp of the most recent mutation.



452
453
454
# File 'lib/smplkit/jobs/models.rb', line 452

def updated_at
  @updated_at
end

#versionInteger?

Returns Monotonic version counter, bumped on every server-side write.

Returns:

  • (Integer, nil)

    Monotonic version counter, bumped on every server-side write.



460
461
462
# File 'lib/smplkit/jobs/models.rb', line 460

def version
  @version
end

Class Method Details

.from_resource(resource, client: nil) ⇒ Job

Returns The hydrated job.

Parameters:

  • resource (Object)

    The JSON:API resource (id + attributes).

  • client (JobsClient, nil) (defaults to: nil)

    Client to bind the job to.

Returns:

  • (Job)

    The hydrated job.



770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
# File 'lib/smplkit/jobs/models.rb', line 770

def self.from_resource(resource, client: nil)
  a = resource.attributes
  environments = (a.environments || {}).each_with_object({}) do |(env_key, env_raw), out|
    out[env_key.to_s] = JobEnvironment.from_wire(env_raw)
  end
  new(
    client,
    id: resource.id,
    name: a.name,
    description: a.description,
    # The base +enabled+ roll-up is derived from +environments+, not read
    # from the wire — the API no longer carries a top-level +enabled+.
    environments: environments,
    kind: a.kind,
    type: a.type || "http",
    schedule: a.schedule,
    timezone: a.timezone,
    retry_policy: a.retry_policy,
    configuration: HttpConfig.from_wire(a.configuration),
    concurrency_policy: a.concurrency_policy || "ALLOW",
    created_at: a.created_at,
    updated_at: a.updated_at,
    deleted_at: a.deleted_at,
    version: a.version
  )
end

Instance Method Details

#_apply(other) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
# File 'lib/smplkit/jobs/models.rb', line 746

def _apply(other)
  @id = other.id
  @name = other.name
  @description = other.description
  @environments = other.environments
  @kind = other.kind
  @type = other.type
  @schedule = other.schedule
  @timezone = other.timezone
  @retry_policy = other.retry_policy
  @configuration = other.configuration
  @concurrency_policy = other.concurrency_policy
  @created_at = other.created_at
  @updated_at = other.updated_at
  @deleted_at = other.deleted_at
  @version = other.version
end

#_environment_override(environment) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the override for environment, creating an empty one if absent.

The per-environment mutators reach through here so an existing override’s other field is preserved when only one of enabled / configuration is being set.



741
742
743
# File 'lib/smplkit/jobs/models.rb', line 741

def _environment_override(environment)
  @environments[environment] ||= JobEnvironment.new
end

#deletenil Also known as: delete!

Delete this job on the server.

Returns:

  • (nil)


513
514
515
516
517
# File 'lib/smplkit/jobs/models.rb', line 513

def delete
  raise "Job was constructed without a client or id; cannot delete" if @client.nil? || @id.nil?

  @client.delete(@id)
end

#enabledBoolean

Returns Derived roll-up: true when the job is enabled in at least one environment. Computed from #environments rather than read from the wire — the API no longer carries a top-level enabled. Set enablement per environment via #set_enabled / #environments.

Returns:

  • (Boolean)

    Derived roll-up: true when the job is enabled in at least one environment. Computed from #environments rather than read from the wire — the API no longer carries a top-level enabled. Set enablement per environment via #set_enabled / #environments.



392
393
394
# File 'lib/smplkit/jobs/models.rb', line 392

def enabled
  (@environments || {}).each_value.any?(&:enabled)
end

#get_configuration(environment: nil) ⇒ HttpConfig

The job’s effective configuration.

With environment omitted (the default), returns the base configuration. With an environment, returns that environment’s configuration override when it has one, else the base configuration —the request the job actually sends when it fires in that environment.

Parameters:

  • environment (String, nil) (defaults to: nil)

    An environment key, or nil for the base configuration.

Returns:



601
602
603
604
605
606
607
# File 'lib/smplkit/jobs/models.rb', line 601

def get_configuration(environment: nil)
  unless environment.nil?
    override = @environments[environment]
    return override.configuration if override && !override.configuration.nil?
  end
  @configuration
end

#is_enabled(environment: nil) ⇒ Boolean

Whether the job is enabled.

With environment omitted (the default), returns the roll-up — true when the job is enabled in at least one environment. With an environment, returns whether the job is enabled in that specific environment.

Parameters:

  • environment (String, nil) (defaults to: nil)

    An environment key, or nil for the roll-up across every environment.

Returns:

  • (Boolean)


542
543
544
545
546
547
548
549
# File 'lib/smplkit/jobs/models.rb', line 542

def is_enabled(environment: nil)
  return enabled if environment.nil?

  override = @environments[environment]
  return false if override.nil?

  override.enabled
end

#is_manualBoolean

Whether this is a manual job — no schedule; runs only when triggered.

Returns:

  • (Boolean)


561
562
563
# File 'lib/smplkit/jobs/models.rb', line 561

def is_manual
  @kind == JobKind::MANUAL
end

#is_one_offBoolean

Whether this is a one-off job — a single now / datetime run.

Returns:

  • (Boolean)


568
569
570
# File 'lib/smplkit/jobs/models.rb', line 568

def is_one_off
  @kind == JobKind::ONE_OFF
end

#is_recurringBoolean

Whether this is a recurring (cron-scheduled) job.

Returns:

  • (Boolean)


554
555
556
# File 'lib/smplkit/jobs/models.rb', line 554

def is_recurring
  @kind == JobKind::RECURRING
end

#list_runs(environment: nil, triggers: nil, last_run_only: false, page_size: nil, after: nil) ⇒ Array<Smplkit::Jobs::Run>

List this job’s run history, most recent first.

Parameters:

  • environment (String, nil) (defaults to: nil)

    Restrict to runs stamped with this environment. nil covers every environment you can access.

  • triggers (Array<String>, nil) (defaults to: nil)

    Restrict to runs started by any of these triggers (see RunTrigger) — e.g. [RunTrigger::RETRY] for automatic retries. nil covers every trigger.

  • last_run_only (Boolean) (defaults to: false)

    When true, return only the last completed run per environment (in-flight runs excluded). Defaults to false.

  • page_size (Integer, nil) (defaults to: nil)

    Maximum number of runs to return in this page.

  • after (String, nil) (defaults to: nil)

    Opaque cursor from a previous page.

Returns:

Raises:

  • (RuntimeError)

    when this job has no bound client.



721
722
723
724
725
726
727
728
729
730
731
732
# File 'lib/smplkit/jobs/models.rb', line 721

def list_runs(environment: nil, triggers: nil, last_run_only: false, page_size: nil, after: nil)
  raise "Job was constructed without a client; cannot list runs" if @client.nil?

  @client.runs.list(
    job: @id,
    environments: environment.nil? ? nil : [environment],
    triggers: triggers,
    last_run_only: last_run_only,
    page_size: page_size,
    after: after
  )
end

#saveself Also known as: save!

Create this job, or full-replace it if it already exists.

Upsert behavior is driven by #created_at: a job with no created_at is created (POST); otherwise it’s full-replace updated (PUT). After the call, every field is refreshed from the server response (including newly-assigned created_at, version, and per-environment next_run_at inside #environments).

Returns:

  • (self)


501
502
503
504
505
506
507
# File 'lib/smplkit/jobs/models.rb', line 501

def save
  raise "Job was constructed without a client; cannot save" if @client.nil?

  updated = @created_at.nil? ? @client._create_job(self) : @client._update_job(self)
  _apply(updated)
  self
end

#set_configuration(configuration, environment: nil) ⇒ Object

Set the job’s configuration — base (environment omitted) or per-environment.

With environment given, sets the per-environment override’s configuration on #environments, creating the override entry if it doesn’t exist yet (preserving any already-set enabled on it). Call #save to persist.

Parameters:

  • configuration (HttpConfig)

    The HTTP request configuration.

  • environment (String, nil) (defaults to: nil)

    An environment key for a per-environment override, or nil to set the base configuration.



583
584
585
586
587
588
589
# File 'lib/smplkit/jobs/models.rb', line 583

def set_configuration(configuration, environment: nil)
  if environment.nil?
    @configuration = configuration
  else
    _environment_override(environment).configuration = configuration
  end
end

#set_enabled(enabled, environment:) ⇒ Object

Enable or disable the job in a single environment.

Sets the per-environment override’s enabled on #environments, creating the override entry if it doesn’t exist yet (preserving any already-set configuration on it). Call #save to persist.

Parameters:

  • enabled (Boolean)

    Whether the job should fire in this environment.

  • environment (String)

    The environment key to enable / disable.



528
529
530
# File 'lib/smplkit/jobs/models.rb', line 528

def set_enabled(enabled, environment:)
  _environment_override(environment).enabled = enabled
end

#set_retry_policy(retry_policy, environment: nil) ⇒ Object

Set the retry policy for failed runs — base (environment omitted) or per-environment.

With environment omitted (the default), sets the base #retry_policy every environment inherits unless it overrides it. With an environment given, sets that environment’s per-environment override on #environments, creating the override entry if it doesn’t exist yet (preserving any already-set enabled / schedule / timezone / configuration on it). Call #save to persist.

Accepts either a RetryPolicy instance (its id is used) or a policy id string — pass “Default” for the built-in never-retry policy.

Parameters:

  • retry_policy (RetryPolicy, String)

    A RetryPolicy or a policy id.

  • environment (String, nil) (defaults to: nil)

    An environment key for a per-environment override, or nil to set the base retry policy.



684
685
686
687
688
689
690
691
# File 'lib/smplkit/jobs/models.rb', line 684

def set_retry_policy(retry_policy, environment: nil)
  policy_id = retry_policy.is_a?(RetryPolicy) ? retry_policy.id : retry_policy
  if environment.nil?
    @retry_policy = policy_id
  else
    _environment_override(environment).retry_policy = policy_id
  end
end

#set_schedule(schedule, timezone: nil, environment: nil) ⇒ Object

Set the job’s schedule — base (environment omitted) or per-environment.

With environment omitted (the default), sets the base #schedule —an ISO-8601 datetime, a 5-field UTC cron expression, or the literal “now” — which every environment inherits unless it overrides it.

With environment given, sets that environment’s per-environment cron schedule override on #environments, creating the override entry if it doesn’t exist yet (preserving any already-set enabled / configuration on it). A per-environment override is a cron expression only and varies the cadence within that environment; it cannot turn a one-off job recurring or vice-versa. Call #save to persist.

Because the timezone is an integral part of a cron cadence, a timezone may be supplied alongside the schedule; when given it sets the same scope’s timezone too (equivalent to a follow-up #set_timezone). Omit it to leave the timezone untouched. For a timezone-only change, use #set_timezone.

Parameters:

  • schedule (String)

    An ISO-8601 datetime, a 5-field UTC cron expression, or the literal “now” (base); a 5-field UTC cron expression (per-environment).

  • timezone (String, nil) (defaults to: nil)

    An optional IANA timezone to set on the same scope (recurring jobs only). nil (the default) leaves the timezone untouched.

  • environment (String, nil) (defaults to: nil)

    An environment key for a per-environment override, or nil to set the base schedule.



636
637
638
639
640
641
642
643
# File 'lib/smplkit/jobs/models.rb', line 636

def set_schedule(schedule, timezone: nil, environment: nil)
  if environment.nil?
    @schedule = schedule
  else
    _environment_override(environment).schedule = schedule
  end
  set_timezone(timezone, environment: environment) unless timezone.nil?
end

#set_timezone(timezone, environment: nil) ⇒ Object

Set the IANA timezone the cron schedule is evaluated in — base (environment omitted) or per-environment.

With environment omitted (the default), sets the base #timezone every environment inherits unless it overrides it. With an environment given, sets that environment’s per-environment timezone override on #environments, creating the override entry if it doesn’t exist yet (preserving any already-set enabled / schedule / configuration on it). A timezone is only valid on a recurring (cron) job; nil means UTC (base) or “inherit the base” (per-environment). Call #save to persist.

Parameters:

  • timezone (String, nil)

    A valid IANA timezone key (e.g. “America/New_York”), or nil for UTC / inherit.

  • environment (String, nil) (defaults to: nil)

    An environment key for a per-environment override, or nil to set the base timezone.



660
661
662
663
664
665
666
# File 'lib/smplkit/jobs/models.rb', line 660

def set_timezone(timezone, environment: nil)
  if environment.nil?
    @timezone = timezone
  else
    _environment_override(environment).timezone = timezone
  end
end

#trigger(environment: nil) ⇒ Smplkit::Jobs::Run

Trigger one immediate, manual run of this job (a MANUAL run).

Parameters:

  • environment (String, nil) (defaults to: nil)

    Environment the run executes in. Defaults to the client’s configured environment; when the job is enabled in exactly one environment that environment is used.

Returns:

Raises:

  • (RuntimeError)

    when this job has no bound client.



700
701
702
703
704
# File 'lib/smplkit/jobs/models.rb', line 700

def trigger(environment: nil)
  raise "Job was constructed without a client; cannot trigger a run" if @client.nil?

  @client.run(@id, environment: environment)
end