Class: Parse::JobStatus

Inherits:
Object
  • Object
show all
Defined in:
lib/parse/model/classes/job_status.rb

Overview

Note:

This collection is written by Parse Server itself and read access typically requires the master key. Parse Server does not garbage-collect _JobStatus rows — long-running deployments accumulate history and should implement their own retention policy.

This class represents the data and columns contained in the standard Parse _JobStatus collection. Parse Server writes a row here every time a background job (registered via Parse.Cloud.job(...)) runs, recording its outcome and any status/message updates emitted via response.message(...).

The default schema for JobStatus is as follows:

class Parse::JobStatus < Parse::Object
 # See Parse::Object for inherited properties...

 property :job_name
 property :source             # how the job was invoked
 property :status             # "running", "succeeded", "failed"
 property :message            # latest status message emitted by the job
 property :params, :object    # parameters the job was invoked with
 property :finished_at, :date # when the job stopped running
end

Defining a job

Jobs are registered in your Parse Server's Cloud Code (server-side JavaScript), not in this Ruby SDK. A minimal example:

// cloud/main.js
Parse.Cloud.job("nightlyCleanup", async (request) => {
 const { params, headers, log, message } = request;
 message("Starting cleanup...");
 const query = new Parse.Query("_Session");
 query.lessThan("expiresAt", new Date());
 const sessions = await query.find({ useMasterKey: true });
 await Parse.Object.destroyAll(sessions, { useMasterKey: true });
 message(`Deleted ${sessions.length} sessions`);
 return `ok`;
});

Invoking a job

Once registered, a job can be triggered ad-hoc via REST (requires the master key):

POST /parse/jobs/nightlyCleanup
X-Parse-Application-Id: ...
X-Parse-Master-Key: ...
Content-Type: application/json

{ "someParam": "value" }

The request returns immediately with a _JobStatus objectId; the job itself runs asynchronously, and the _JobStatus row is updated as it progresses. For recurring runs, configure a JobSchedule row via the Parse Dashboard's "Jobs" tab — Parse Server's scheduler will invoke the job at the configured times.

Reading job status from Ruby

# Has the nightly cleanup run today?
latest = Parse::JobStatus.latest_for("nightlyCleanup")
puts "Last run: #{latest.status} at #{latest.created_at}"
puts "Duration: #{latest.duration}s" if latest.finished?

# Find failed jobs in the last 24h
yesterday = Time.now - 86_400
Parse::JobStatus.failed.where(:created_at.gt => yesterday).all

Constant Summary collapse

STATUS_RUNNING =

Parse Server's terminal status values, written by setFinalStatus in StatusHandler.js. Mirrored here so callers can compare against named constants instead of hard-coding strings.

"running"
STATUS_SUCCEEDED =
"succeeded"
STATUS_FAILED =
"failed"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#finished_atParse::Date

Timestamp when the job stopped running. Nil while the job is still in-flight.

Returns:



127
# File 'lib/parse/model/classes/job_status.rb', line 127

property :finished_at, :date

#job_nameString

The name the job was registered under (the first argument to Parse.Cloud.job).

Returns:



96
# File 'lib/parse/model/classes/job_status.rb', line 96

property :job_name

#messageString

The most recent status message emitted by the job via response.message(...).

Returns:



116
# File 'lib/parse/model/classes/job_status.rb', line 116

property :message

#paramsHash

The parameters the job was invoked with.

Returns:



121
# File 'lib/parse/model/classes/job_status.rb', line 121

property :params, :object

#sourceString

How the job was invoked. Parse Server itself hard-codes "api" in StatusHandler.js for runs triggered via POST /parse/jobs/<name>; external schedulers (parse-server-scheduler, dashboard cron tooling) may inject other values when they create the _JobStatus row.

Returns:



104
# File 'lib/parse/model/classes/job_status.rb', line 104

property :source

#statusString

Current state of the job run. Common values are "running", "succeeded", and "failed".

Returns:



110
# File 'lib/parse/model/classes/job_status.rb', line 110

property :status

Class Method Details

.cleanup_older_than!(days: 30, terminal_only: true) ⇒ Integer

Delete _JobStatus rows older than the given threshold. Parse Server does not garbage-collect this collection on its own, so long-running deployments accumulate run history indefinitely. Mirrors Installation.cleanup_stale_tokens!.

By default (terminal_only: true), only rows in a terminal state (succeeded or failed) are eligible — an orphaned status == "running" row from a crashed worker is preserved, as is any row with an external-scheduler-injected status the SDK doesn't recognize. Set terminal_only: false to drop the status guard and reap every row older than the cutoff regardless of state (use with care for orphan cleanup).

Use with caution — permanently removes job-history records.

Examples:

deleted = Parse::JobStatus.cleanup_older_than!(days: 90)

Parameters:

  • days (Integer) (defaults to: 30)

    number of days since created_at (default: 30). Negative values are accepted and produce a future cutoff (useful in tests for "delete everything older than now-plus-a-minute").

  • terminal_only (Boolean) (defaults to: true)

    when true (default), restrict the destroy to rows whose status is succeeded or failed. When false, every row older than the cutoff is eligible.

Returns:

  • (Integer)

    the number of rows deleted



222
223
224
225
226
227
228
229
230
# File 'lib/parse/model/classes/job_status.rb', line 222

def cleanup_older_than!(days: 30, terminal_only: true)
  scope = older_than(days: days)
  if terminal_only
    scope = scope.where(:status.in => [STATUS_SUCCEEDED, STATUS_FAILED])
  end
  stale = scope.all
  stale.each(&:destroy)
  stale.count
end

.failedParse::Query

Query for jobs that failed.

Returns:



151
152
153
# File 'lib/parse/model/classes/job_status.rb', line 151

def failed
  query(status: STATUS_FAILED)
end

.for_job(name) ⇒ Parse::Query

Query scope for runs of a specific job by name.

Parameters:

Returns:



165
166
167
# File 'lib/parse/model/classes/job_status.rb', line 165

def for_job(name)
  query(job_name: name.to_s)
end

.latest_for(name) ⇒ Parse::JobStatus?

The most recently started run of the named job (any status), ordered by created_at. Useful for "did the nightly cleanup run yet?" introspection. Note that for a still-running job this may return the in-flight row even after subsequent attempts have finished — created_at is the start time, not the finish time.

Parameters:

Returns:



176
177
178
# File 'lib/parse/model/classes/job_status.rb', line 176

def latest_for(name)
  for_job(name).order(:created_at.desc).first
end

.older_than(days: 30) ⇒ Parse::Query

Query scope for _JobStatus rows older than the given threshold.

Examples:

stale = Parse::JobStatus.older_than(days: 90).all

Parameters:

  • days (Integer) (defaults to: 30)

    number of days since the row's created_at (default: 30)

Returns:



186
187
188
189
# File 'lib/parse/model/classes/job_status.rb', line 186

def older_than(days: 30)
  cutoff = Time.now - (days * 24 * 60 * 60)
  query(:created_at.lt => cutoff)
end

.older_than_count(days: 30) ⇒ Integer

Count _JobStatus rows older than the given threshold.

Parameters:

  • days (Integer) (defaults to: 30)

    number of days since created_at (default: 30)

Returns:

  • (Integer)


194
195
196
# File 'lib/parse/model/classes/job_status.rb', line 194

def older_than_count(days: 30)
  older_than(days: days).count
end

.recent(limit: 100) ⇒ Parse::Query

Query for the most recent job status rows, newest first.

Parameters:

  • limit (Integer) (defaults to: 100)

    number of rows to return (default: 100)

Returns:



158
159
160
# File 'lib/parse/model/classes/job_status.rb', line 158

def recent(limit: 100)
  query.order(:created_at.desc).limit(limit)
end

.runningParse::Query

Query for jobs currently in the running state.

Returns:



139
140
141
# File 'lib/parse/model/classes/job_status.rb', line 139

def running
  query(status: STATUS_RUNNING)
end

.succeededParse::Query

Query for jobs that completed successfully.

Returns:



145
146
147
# File 'lib/parse/model/classes/job_status.rb', line 145

def succeeded
  query(status: STATUS_SUCCEEDED)
end

Instance Method Details

#durationFloat?

Wall-clock duration of the run as a Float number of seconds, or nil while the job is still in-flight (or if either timestamp is missing).

Returns:

  • (Float, nil)


259
260
261
262
# File 'lib/parse/model/classes/job_status.rb', line 259

def duration
  return nil if finished_at.nil? || created_at.nil?
  finished_at.to_time - created_at.to_time
end

#failed?Boolean

Returns true if this run failed.

Returns:

  • (Boolean)

    true if this run failed.



244
245
246
# File 'lib/parse/model/classes/job_status.rb', line 244

def failed?
  status == STATUS_FAILED
end

#finished?Boolean

Returns true if the run has reached a terminal state (succeeded or failed). Parse Server writes finished_at at the same time it transitions out of running, so either signal is acceptable; we check finished_at first because it's the more authoritative one.

Returns:

  • (Boolean)

    true if the run has reached a terminal state (succeeded or failed). Parse Server writes finished_at at the same time it transitions out of running, so either signal is acceptable; we check finished_at first because it's the more authoritative one.



252
253
254
# File 'lib/parse/model/classes/job_status.rb', line 252

def finished?
  !finished_at.nil? || succeeded? || failed?
end

#running?Boolean

Returns true if this row is in the running state.

Returns:

  • (Boolean)

    true if this row is in the running state.



234
235
236
# File 'lib/parse/model/classes/job_status.rb', line 234

def running?
  status == STATUS_RUNNING
end

#succeeded?Boolean

Returns true if this run completed successfully.

Returns:

  • (Boolean)

    true if this run completed successfully.



239
240
241
# File 'lib/parse/model/classes/job_status.rb', line 239

def succeeded?
  status == STATUS_SUCCEEDED
end