Class: SolidQueue::Record
- Inherits:
-
Object
- Object
- SolidQueue::Record
- Includes:
- Mongoid::Document, Mongoid::Timestamps
- Defined in:
- lib/solid_queue_mongoid/models/record.rb
Direct Known Subclasses
Execution, Job, Pause, Process, RecurringExecution, RecurringTask, Semaphore
Constant Summary collapse
- INDEX_HINTS =
Subclasses declare their MySQL index name → MongoDB field spec mappings here.
{}.freeze
Class Method Summary collapse
-
.create_or_find_by!(attrs, &block) ⇒ Object
Mongoid equivalent of ActiveRecord's create_or_find_by!.
-
.find_by!(attrs) ⇒ Object
find_by that raises Mongoid::Errors::DocumentNotFound when missing.
-
.index(spec, options = nil) ⇒ Object
Override Mongoid's index() to use our per-class storage.
- .index_specifications ⇒ Object
- .index_specifications=(val) ⇒ Object
-
.inherited(subclass) ⇒ Object
Dynamic collection naming with prefix.
-
.non_blocking_lock ⇒ Object
MongoDB has no row-level locking; this is a no-op stub so SolidQueue code that chains .non_blocking_lock still works.
-
.supports_insert_conflict_target? ⇒ Boolean
MongoDB supports unique indexes which serve the same purpose.
-
.transaction(_requires_new: false, &block) ⇒ Object
Mongoid 9 supports multi-document transactions via replica sets.
-
.use_index(*indexes) ⇒ Object
Translate solid_queue MySQL index names to MongoDB hint specs and apply via Mongoid's .hint().
Class Method Details
.create_or_find_by!(attrs, &block) ⇒ Object
Mongoid equivalent of ActiveRecord's create_or_find_by!. Tries to create; on duplicate-key error or uniqueness validation error finds the existing record. Falls back to finding by job_id alone when the full attrs lookup would miss the existing record (e.g. queue_name is not in attrs but was set via a before_create callback).
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 95 def create_or_find_by!(attrs, &block) record = new(attrs) block.call(record) if block_given? record.save! record rescue Mongoid::Errors::Validations => e # If the only errors are uniqueness-related, fall back to find the existing record raise unless uniqueness_only_error?(e.document) find_by_unique_key(attrs) || where(attrs).first || record rescue Mongo::Error::OperationFailure => e raise unless duplicate_key_error?(e) find_by_unique_key(attrs) || where(attrs).first || raise(e) end |
.find_by!(attrs) ⇒ Object
find_by that raises Mongoid::Errors::DocumentNotFound when missing.
112 113 114 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 112 def find_by!(attrs) find_by(attrs) || raise(Mongoid::Errors::DocumentNotFound.new(self, attrs)) end |
.index(spec, options = nil) ⇒ Object
Override Mongoid's index() to use our per-class storage.
24 25 26 27 28 29 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 24 def index(spec, = nil) specification = Mongoid::Indexable::Specification.new(self, spec, ) return if index_specifications.include?(specification) index_specifications.push(specification) end |
.index_specifications ⇒ Object
15 16 17 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 15 def index_specifications @index_specifications ||= [] end |
.index_specifications=(val) ⇒ Object
19 20 21 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 19 def index_specifications=(val) @_sq_index_specs = val end |
.inherited(subclass) ⇒ Object
Dynamic collection naming with prefix
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 33 def self.inherited(subclass) super collection_name = subclass.name.demodulize.tableize prefixed_name = "#{SolidQueue.collection_prefix}#{collection_name}" subclass.store_in collection: prefixed_name, client: -> { SolidQueue.client.to_s } # Each subclass gets its own empty index_specifications array. # Indexes must be explicitly defined in each subclass (not inherited from parent) # because Mongoid::Indexable::Specification stores a reference to the klass, # and copying parent specs would create indexes on the parent's collection. subclass.instance_variable_set(:@_sq_index_specs, []) end |
.non_blocking_lock ⇒ Object
MongoDB has no row-level locking; this is a no-op stub so SolidQueue code that chains .non_blocking_lock still works.
51 52 53 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 51 def non_blocking_lock all end |
.supports_insert_conflict_target? ⇒ Boolean
MongoDB supports unique indexes which serve the same purpose.
66 67 68 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 66 def supports_insert_conflict_target? true end |
.transaction(_requires_new: false, &block) ⇒ Object
Mongoid 9 supports multi-document transactions via replica sets. We wrap in a MongoDB session transaction when available; fall back to a plain yield for non-replica-set environments (e.g. tests with a standalone).
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 73 def transaction(_requires_new: false, &block) Mongoid::QueryCache.clear_cache Mongoid.default_client.with_session do |session| session.start_transaction result = yield session.commit_transaction result end rescue Mongo::Error::InvalidSession, Mongo::Error::OperationFailure => e # Not in a replica set or session not supported — execute without transaction raise if e..to_s.include?("Transaction numbers are only allowed") yield rescue StandardError yield end |
.use_index(*indexes) ⇒ Object
Translate solid_queue MySQL index names to MongoDB hint specs and apply via Mongoid's .hint(). Unknown names are ignored (no hint applied). Subclasses may override INDEX_HINTS to register their own mappings.
58 59 60 61 62 63 |
# File 'lib/solid_queue_mongoid/models/record.rb', line 58 def use_index(*indexes) specs = indexes.filter_map do |name| name.is_a?(Hash) ? name : self::INDEX_HINTS[name.to_sym] end specs.any? ? hint(specs.first) : all end |