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, 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.



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
# File 'lib/smplkit/jobs/models.rb', line 438

def initialize(client = nil, id:, name:, configuration:, schedule: nil,
               timezone: 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
  @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



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

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.



415
416
417
# File 'lib/smplkit/jobs/models.rb', line 415

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.



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

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.



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

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.



426
427
428
# File 'lib/smplkit/jobs/models.rb', line 426

def deleted_at
  @deleted_at
end

#descriptionString?

Returns Free-text description. nil when unset.

Returns:

  • (String, nil)

    Free-text description. nil when unset.



363
364
365
# File 'lib/smplkit/jobs/models.rb', line 363

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.



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

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.



357
358
359
# File 'lib/smplkit/jobs/models.rb', line 357

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:



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

def kind
  @kind
end

#nameString

Returns Human-readable name for the job.

Returns:

  • (String)

    Human-readable name for the job.



360
361
362
# File 'lib/smplkit/jobs/models.rb', line 360

def name
  @name
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.



397
398
399
# File 'lib/smplkit/jobs/models.rb', line 397

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.



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

def timezone
  @timezone
end

#typeString

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

Returns:

  • (String)

    Job type. Only “http” is supported today.



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

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.



422
423
424
# File 'lib/smplkit/jobs/models.rb', line 422

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.



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

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.



695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
# File 'lib/smplkit/jobs/models.rb', line 695

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,
    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.



672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
# File 'lib/smplkit/jobs/models.rb', line 672

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
  @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.



667
668
669
# File 'lib/smplkit/jobs/models.rb', line 667

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

#deletenil Also known as: delete!

Delete this job on the server.

Returns:

  • (nil)


482
483
484
485
486
# File 'lib/smplkit/jobs/models.rb', line 482

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.



369
370
371
# File 'lib/smplkit/jobs/models.rb', line 369

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:



570
571
572
573
574
575
576
# File 'lib/smplkit/jobs/models.rb', line 570

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)


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

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)


530
531
532
# File 'lib/smplkit/jobs/models.rb', line 530

def is_manual
  @kind == JobKind::MANUAL
end

#is_one_offBoolean

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

Returns:

  • (Boolean)


537
538
539
# File 'lib/smplkit/jobs/models.rb', line 537

def is_one_off
  @kind == JobKind::ONE_OFF
end

#is_recurringBoolean

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

Returns:

  • (Boolean)


523
524
525
# File 'lib/smplkit/jobs/models.rb', line 523

def is_recurring
  @kind == JobKind::RECURRING
end

#list_runs(environment: nil, 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.

  • 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.



649
650
651
652
653
654
655
656
657
658
# File 'lib/smplkit/jobs/models.rb', line 649

def list_runs(environment: nil, 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],
    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)


470
471
472
473
474
475
476
# File 'lib/smplkit/jobs/models.rb', line 470

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.



552
553
554
555
556
557
558
# File 'lib/smplkit/jobs/models.rb', line 552

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.



497
498
499
# File 'lib/smplkit/jobs/models.rb', line 497

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

#set_schedule(schedule, 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.

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).

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

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



596
597
598
599
600
601
602
# File 'lib/smplkit/jobs/models.rb', line 596

def set_schedule(schedule, environment: nil)
  if environment.nil?
    @schedule = schedule
  else
    _environment_override(environment).schedule = schedule
  end
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.



619
620
621
622
623
624
625
# File 'lib/smplkit/jobs/models.rb', line 619

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.



634
635
636
637
638
# File 'lib/smplkit/jobs/models.rb', line 634

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

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