class Mongoid::Contextual::Mongo::DocumentsLoader
Loads documents for the provided criteria.
@api private
Attributes
@return [ Mongoid::Criteria
] Criteria
that specifies which documents should
be loaded. Exposed here because `eager_loadable?` method from `Association::EagerLoadable` expects this to be available.
Public Class Methods
Returns suitable executor according to Mongoid
config options.
@param [ String | Symbol] name The query executor name, can be either
:immediate or :global_thread_pool. Defaulted to `async_query_executor` config option.
@return [ Concurrent::ImmediateExecutor | Concurrent::ThreadPoolExecutor ] The executor
to be used to execute document loading tasks.
@raise [ Errors::InvalidQueryExecutor
] If an unknown name is provided.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 61 def self.executor(name = Mongoid.async_query_executor) case name.to_sym when :immediate immediate_executor when :global_thread_pool global_thread_pool_async_query_executor else raise Errors::InvalidQueryExecutor.new(name) end end
Returns asynchronous executor to be used when async_query_executor config option is set to :global_thread_pool. This executor runs operations on background threads using a thread pool.
@return [ Concurrent::ThreadPoolExecutor ] The executor
to be used to execute document loading tasks.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 32 def self.global_thread_pool_async_query_executor create_pool = Proc.new do |concurrency| Concurrent::ThreadPoolExecutor.new( min_threads: 0, max_threads: concurrency, max_queue: concurrency * 4, fallback_policy: :caller_runs ) end concurrency = Mongoid.global_executor_concurrency || 4 @@global_thread_pool_async_query_executor ||= create_pool.call(concurrency) if @@global_thread_pool_async_query_executor.max_length != concurrency old_pool = @@global_thread_pool_async_query_executor @@global_thread_pool_async_query_executor = create_pool.call(concurrency) old_pool.shutdown end @@global_thread_pool_async_query_executor end
Returns synchronous executor to be used when async_query_executor config option is set to :immediate. This executor runs all operations on the current thread, blocking as necessary.
@return [ Concurrent::ImmediateExecutor ] The executor
to be used to execute document loading tasks.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 22 def self.immediate_executor @@immediate_executor ||= Concurrent::ImmediateExecutor.new end
Instantiates the document loader instance and immediately schedules its execution using the provided executor.
@param [ Mongo::Collection::View ] view The collection view to get
records from the database.
@param [ Class ] klass Mongoid
model class to instantiate documents.
All records obtained from the database will be converted to an instance of this class, if possible.
@param [ Mongoid::Criteria
] criteria Criteria
that specifies which
documents should be loaded.
@param [ Concurrent::AbstractExecutorService ] executor Executor that
is capable of running `Concurrent::Promises::Future` instances.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 89 def initialize(view, klass, criteria, executor: self.class.executor) @view = view @klass = klass @criteria = criteria @mutex = Mutex.new @state = :pending @future = Concurrent::Promises.future_on(executor) do start && execute end end
Public Instance Methods
Loads records specified by ‘@criteria` from the database, and convert them to Mongoid
documents of `@klass` type.
This method is called by the task (possibly asynchronous) scheduled when creating an instance of the loader. However, this method can be called directly, if it is desired to execute loading on the caller thread immediately.
Calling this method does not change the state of the loader.
@return [ Array<Mongoid::Document> ] Array of document loaded from
the database.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 152 def execute documents = @view.map do |doc| Factory.from_db(@klass, doc, @criteria) end eager_load(documents) if eager_loadable? documents end
Returns false or true whether the loader is in pending state.
Pending state means that the loader execution has been scheduled, but has not been started yet.
@return [ true | false ] true if the loader is in pending state,
otherwise false.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 107 def pending? @mutex.synchronize do @state == :pending end end
Returns false or true whether the loader is in started state.
Started state means that the loader execution has been started. Note that the loader stays in this state even after the execution completed (successfully or failed).
@return [ true | false ] true if the loader is in started state,
otherwise false.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 121 def started? @mutex.synchronize do @state == :started end end
Mark the loader as unscheduled.
If the loader is marked unscheduled, it will not be executed. The only option to load the documents is to call ‘execute` method directly.
Please note that if execution of a task has been already started, unscheduling does not have any effect.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 134 def unschedule @mutex.synchronize do @state = :cancelled unless @state == :started end end
Private Instance Methods
Mark the loader as started if possible.
@return [ true | false ] Whether the state was changed to :started.
# File lib/mongoid/contextual/mongo/documents_loader.rb, line 165 def start @mutex.synchronize do if @state == :pending @state = :started true else false end end end