Class: Parse::JobStatus
- Defined in:
- lib/parse/model/classes/job_status.rb
Overview
This collection is written by Parse Server itself and read access
requires the master key. _JobStatus is hardcoded master-key-only at
Parse Server's REST layer (SharedRest.js) — CLP changes via
Object.set_clp have no effect. Use a master-key client (or a
Cloud Code function) to read it. 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: #latestlatest.status at #latestlatest.created_at" puts "Duration: #latestlatest.durations" 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"
Constants inherited from Object
Object::BUILTIN_PARSE_CLASS_NAMES, Object::IDENTIFICATION_FIELDS, Object::VALID_ACL_POLICIES
Constants included from Core::Schema
Core::Schema::DEFAULT_PUBLIC_CLP, Core::Schema::SCHEMA_READONLY_CLASSES
Constants included from Core::Describe
Core::Describe::ALL_SECTIONS, Core::Describe::CORE_FIELD_KEYS, Core::Describe::LOCAL_SECTIONS, Core::Describe::NETWORK_SECTIONS
Constants included from Core::Indexing
Core::Indexing::MAX_INDEXES_PER_COLLECTION, Core::Indexing::PARSE_MANAGED_ARRAY_FIELDS, Core::Indexing::SENSITIVE_FIELDS
Constants included from Core::SearchIndexing
Core::SearchIndexing::ALLOWED_INDEX_TYPES, Core::SearchIndexing::INDEX_NAME_PATTERN
Constants included from Core::Fetching
Core::Fetching::NON_SERIALIZABLE_IVARS
Constants included from Core::EmbedManaged
Core::EmbedManaged::WRITER_KEY
Constants included from Core::ParseReference
Core::ParseReference::OBJECT_ID_LENGTH, Core::ParseReference::SEPARATOR
Constants included from Core::FieldGuards
Core::FieldGuards::GUARD_MODES
Constants included from Properties
Properties::BASE, Properties::BASE_FIELD_MAP, Properties::BASE_KEYS, Properties::CORE_FIELDS, Properties::DELETE_OP, Properties::PROTECTED_INITIALIZE_KEYS, Properties::PROTECTED_MASS_ASSIGNMENT_KEYS, Properties::TYPES
Constants inherited from Pointer
Pointer::ATTRIBUTES, Pointer::OBJECT_ID_FORMAT
Constants inherited from Model
Model::CLASS_AUDIENCE, Model::CLASS_INSTALLATION, Model::CLASS_JOB_SCHEDULE, Model::CLASS_JOB_STATUS, Model::CLASS_PRODUCT, Model::CLASS_PUSH_STATUS, Model::CLASS_ROLE, Model::CLASS_SCHEMA, Model::CLASS_SESSION, Model::CLASS_USER, Model::ID, Model::KEY_CLASS_NAME, Model::KEY_CREATED_AT, Model::KEY_OBJECT_ID, Model::KEY_UPDATED_AT, Model::OBJECT_ID, Model::TYPE_ACL, Model::TYPE_BYTES, Model::TYPE_DATE, Model::TYPE_FIELD, Model::TYPE_FILE, Model::TYPE_GEOPOINT, Model::TYPE_NUMBER, Model::TYPE_OBJECT, Model::TYPE_POINTER, Model::TYPE_POLYGON, Model::TYPE_RELATION
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.
Attributes inherited from Object
#acl, #created_at, #id, #updated_at
Attributes inherited from Pointer
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.
Methods inherited from Object
#[], #[]=, #__type, #_resolve_acl_owner_id, #_resolve_default_acl, #acl_changed?, acl_owner_field, acl_policy, acl_policy_setting, #acl_was, #acl_will_change!, #after_create, #after_destroy, #after_save, #after_update, #after_validation, #apply_defaults!, #around_create, #around_destroy, #around_save, #around_update, #around_validation, #as_json, #autofetch_disabled?, #before_create, #before_destroy, #before_save, #before_update, #before_validation, build, #changed, #changed?, class_permissions, #clear_attribute_change!, #clear_changes!, #clear_partial_fetch_state!, default_acls, describe_access, #disable_autofetch!, #enable_autofetch!, #existed?, fetch_clp, #fetched?, #fetched_keys, #fetched_keys=, #field_was_fetched?, #filter_for_user, filter_results_for_user, #fully_fetched?, #has?, #has_selective_keys?, #initialize, #keys, master_only_class!, #nested_fetched_keys, #nested_fetched_keys=, #nested_keys_for, #new?, #parse_class, #partially_fetched?, #persisted?, pointer, #pretty, private_acl!, protect_fields, #reload!, roles_for_user, #rollback!, #run_after_create_callbacks, #run_after_delete_callbacks, #run_after_save_callbacks, #schema, #search_highlights, #search_score, set_class_access, set_clp, set_default_acl, set_default_clp, set_read_user_fields, set_write_user_fields, #twin, unlistable_class!, update_clp!, #updates, #valid?, #validate!, #vector_score, wait_for, watch, webhook, webhook_function
Methods included from Core::Querying
#all, #all_as, #count, #count_distinct, #cursor, #distinct, #each, #find, #find_cached, #first, #first_as, #last_updated, #latest, #literal_where, #newest, #oldest, #query, #scope, #subscribe
Methods included from Core::Schema
#_default_class_level_permissions_for_upgrade, #auto_upgrade!, #create_schema, #fetch_schema, #reset_clp!, #schema, #update_schema
Methods included from Core::Describe
Methods included from Core::Indexing
#apply_indexes!, #indexes_plan, #mongo_geo_index, #mongo_index, #mongo_index_declarations, #mongo_relation_index
Methods included from Core::SearchIndexing
#apply_search_indexes!, #mongo_search_index, #mongo_search_index_declarations, #search_indexes_plan
Methods included from Core::VectorSearchable
Methods included from Agent::MetadataDSL
#agent_description, #agent_methods, #property_descriptions, #property_enum_descriptions
Methods included from Core::Actions
#_deleted?, #change_requests, #changes_applied!, #changes_payload, #create, #destroy, #destroy_request, #op_add!, #op_add_relation!, #op_add_unique!, #op_destroy!, #op_increment!, #op_remove!, #op_remove_relation!, #operate_field!, #prepare_save!, #relation_change_operations, #save, #save!, #set_attributes!, #update, #update!, #update_relations, #uri_path
Methods included from Core::Fetching
#autofetch!, #fetch, #fetch!, #fetch_cache!, #fetch_json, #fetch_object, #prepare_for_dirty_tracking!
Methods included from Associations::HasMany
has_many, #relation_changes?, #relation_updates, #relations
Methods included from Associations::BelongsTo
Methods included from Associations::HasOne
Methods included from Core::ParseReference
format, generate_object_id, parse
Methods included from Core::FieldGuards
Methods included from Properties
#apply_attributes!, #attribute_changes?, #attribute_updates, #attributes, #attributes=, #field_map, #fields, #format_operation, #format_value
Methods inherited from Pointer
#==, #[], #[]=, #__type, #attributes, #className, #fetch, #fetch_cache!, #fetch_json, #fetch_object, #fetched?, #hash, #initialize, #json_hash, #method_missing, #pointer, #pointer?, #present?, #respond_to_missing?, #search_highlights, #search_score, #sig, #vector_score
Methods inherited from Model
#dirty?, find_class, same_parse_class?
Methods included from Client::Connectable
Constructor Details
This class inherits a constructor from Parse::Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Parse::Pointer
Instance Attribute Details
#finished_at ⇒ Parse::Date
Timestamp when the job stopped running. Nil while the job is still in-flight.
130 |
# File 'lib/parse/model/classes/job_status.rb', line 130 property :finished_at, :date |
#job_name ⇒ String
The name the job was registered under (the first argument to +Parse.Cloud.job+).
99 |
# File 'lib/parse/model/classes/job_status.rb', line 99 property :job_name |
#message ⇒ String
The most recent status message emitted by the job via +response.message(...)+.
119 |
# File 'lib/parse/model/classes/job_status.rb', line 119 property :message |
#params ⇒ Hash
The parameters the job was invoked with.
124 |
# File 'lib/parse/model/classes/job_status.rb', line 124 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/
107 |
# File 'lib/parse/model/classes/job_status.rb', line 107 property :source |
#status ⇒ String
Current state of the job run. Common values are +"running"+, +"succeeded"+, and +"failed"+.
113 |
# File 'lib/parse/model/classes/job_status.rb', line 113 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.
225 226 227 228 229 230 231 232 233 |
# File 'lib/parse/model/classes/job_status.rb', line 225 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.
154 155 156 |
# File 'lib/parse/model/classes/job_status.rb', line 154 def failed query(status: STATUS_FAILED) end |
.for_job(name) ⇒ Parse::Query
Query scope for runs of a specific job by name.
168 169 170 |
# File 'lib/parse/model/classes/job_status.rb', line 168 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.
179 180 181 |
# File 'lib/parse/model/classes/job_status.rb', line 179 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.
189 190 191 192 |
# File 'lib/parse/model/classes/job_status.rb', line 189 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.
197 198 199 |
# File 'lib/parse/model/classes/job_status.rb', line 197 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.
161 162 163 |
# File 'lib/parse/model/classes/job_status.rb', line 161 def recent(limit: 100) query.order(:created_at.desc).limit(limit) end |
.running ⇒ Parse::Query
Query for jobs currently in the running state.
142 143 144 |
# File 'lib/parse/model/classes/job_status.rb', line 142 def running query(status: STATUS_RUNNING) end |
.succeeded ⇒ Parse::Query
Query for jobs that completed successfully.
148 149 150 |
# File 'lib/parse/model/classes/job_status.rb', line 148 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).
262 263 264 265 |
# File 'lib/parse/model/classes/job_status.rb', line 262 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.
247 248 249 |
# File 'lib/parse/model/classes/job_status.rb', line 247 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.
255 256 257 |
# File 'lib/parse/model/classes/job_status.rb', line 255 def finished? !finished_at.nil? || succeeded? || failed? end |
#running? ⇒ Boolean
Returns true if this row is in the running state.
237 238 239 |
# File 'lib/parse/model/classes/job_status.rb', line 237 def running? status == STATUS_RUNNING end |
#succeeded? ⇒ Boolean
Returns true if this run completed successfully.
242 243 244 |
# File 'lib/parse/model/classes/job_status.rb', line 242 def succeeded? status == STATUS_SUCCEEDED end |