Class: Parse::JobStatus
- Inherits:
-
Object
- Object
- Object
- Parse::JobStatus
- Defined in:
- lib/parse/model/classes/job_status.rb
Overview
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
setFinalStatusinStatusHandler.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
-
#finished_at ⇒ Parse::Date
Timestamp when the job stopped running.
-
#job_name ⇒ String
The name the job was registered under (the first argument to
Parse.Cloud.job). -
#message ⇒ String
The most recent status message emitted by the job via
response.message(...). -
#params ⇒ Hash
The parameters the job was invoked with.
-
#source ⇒ String
How the job was invoked.
-
#status ⇒ String
Current state of the job run.
Class Method Summary collapse
-
.cleanup_older_than!(days: 30, terminal_only: true) ⇒ Integer
Delete
_JobStatusrows older than the given threshold. -
.failed ⇒ Parse::Query
Query for jobs that failed.
-
.for_job(name) ⇒ Parse::Query
Query scope for runs of a specific job by name.
-
.latest_for(name) ⇒ Parse::JobStatus?
The most recently started run of the named job (any status), ordered by
created_at. -
.older_than(days: 30) ⇒ Parse::Query
Query scope for
_JobStatusrows older than the given threshold. -
.older_than_count(days: 30) ⇒ Integer
Count
_JobStatusrows older than the given threshold. -
.recent(limit: 100) ⇒ Parse::Query
Query for the most recent job status rows, newest first.
-
.running ⇒ Parse::Query
Query for jobs currently in the running state.
-
.succeeded ⇒ Parse::Query
Query for jobs that completed successfully.
Instance Method Summary collapse
-
#duration ⇒ Float?
Wall-clock duration of the run as a
Floatnumber of seconds, ornilwhile the job is still in-flight (or if either timestamp is missing). -
#failed? ⇒ Boolean
True if this run failed.
-
#finished? ⇒ Boolean
True if the run has reached a terminal state (succeeded or failed).
-
#running? ⇒ Boolean
True if this row is in the running state.
-
#succeeded? ⇒ Boolean
True if this run completed successfully.
Instance Attribute Details
#finished_at ⇒ Parse::Date
Timestamp when the job stopped running. Nil while the job is still in-flight.
127 |
# File 'lib/parse/model/classes/job_status.rb', line 127 property :finished_at, :date |
#job_name ⇒ String
The name the job was registered under (the first argument to
Parse.Cloud.job).
96 |
# File 'lib/parse/model/classes/job_status.rb', line 96 property :job_name |
#message ⇒ String
The most recent status message emitted by the job via
response.message(...).
116 |
# File 'lib/parse/model/classes/job_status.rb', line 116 property :message |
#params ⇒ Hash
The parameters the job was invoked with.
121 |
# File 'lib/parse/model/classes/job_status.rb', line 121 property :params, :object |
#source ⇒ String
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.
104 |
# File 'lib/parse/model/classes/job_status.rb', line 104 property :source |
#status ⇒ String
Current state of the job run. Common values are "running",
"succeeded", and "failed".
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.
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 |
.failed ⇒ Parse::Query
Query for jobs that failed.
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.
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.
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.
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.
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.
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 |
.running ⇒ Parse::Query
Query for jobs currently in the running state.
139 140 141 |
# File 'lib/parse/model/classes/job_status.rb', line 139 def running query(status: STATUS_RUNNING) end |
.succeeded ⇒ Parse::Query
Query for jobs that completed successfully.
145 146 147 |
# File 'lib/parse/model/classes/job_status.rb', line 145 def succeeded query(status: STATUS_SUCCEEDED) end |
Instance Method Details
#duration ⇒ Float?
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).
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.
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.
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.
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.
239 240 241 |
# File 'lib/parse/model/classes/job_status.rb', line 239 def succeeded? status == STATUS_SUCCEEDED end |