Module: Mongoid::Threaded
- Extended by:
- Threaded
- Included in:
- Threaded
- Defined in:
- lib/mongoid/threaded.rb,
lib/mongoid/threaded/lifecycle.rb
Overview
This module contains logic for easy access to objects that have a lifecycle on the current thread.
Defined Under Namespace
Modules: Lifecycle
Constant Summary collapse
- STORAGE_KEY =
The key for the shared thread- and fiber-local storage. It must be a symbol because keys for fiber-local storage must be symbols.
:'[mongoid]'- DATABASE_OVERRIDE_KEY =
'db-override'- CLIENT_OVERRIDE_KEY =
The key to override the client.
'client-override'- CURRENT_SCOPE_KEY =
The key for the current thread’s scope stack.
'current-scope'- AUTOSAVES_KEY =
'autosaves'- VALIDATIONS_KEY =
'validations'- STACK_KEYS =
Hash.new do |hash, key| hash[key] = "#{key}-stack" end
- SESSIONS_KEY =
The key for the current thread’s sessions.
'sessions'- MODIFIED_DOCUMENTS_KEY =
The key for storing documents modified inside transactions.
'modified-documents'- EXECUTE_CALLBACKS =
The key storing the default value for whether or not callbacks are executed on documents.
'execute-callbacks'- BIND =
'bind'.freeze
- ASSIGN =
'assign'.freeze
- BUILD =
'build'.freeze
- LOAD =
'load'.freeze
- CREATE =
'create'.freeze
Instance Method Summary collapse
-
#add_modified_document(session, document) ⇒ Object
Store a reference to the document that was modified inside a transaction associated with the session.
-
#autosaved?(document) ⇒ true | false
Is the document autosaved on the current thread?.
-
#autosaves ⇒ Hash
Get all autosaves on the current thread.
-
#autosaves_for(klass) ⇒ Array
Get all autosaves on the current thread for the class.
-
#begin_autosave(document) ⇒ Object
Begin autosaving a document on the current thread.
-
#begin_execution(name) ⇒ true
Begin entry into a named thread local stack.
-
#begin_validate(document) ⇒ Object
Begin validating a document on the current thread.
-
#begin_without_default_scope(klass) ⇒ Object
private
Begin suppressing default scopes for given model on the current thread.
-
#clear_modified_documents(session) ⇒ Set<Mongoid::Document>
Clears the set of modified documents for the given session, and return the content of the set before the clearance.
-
#clear_session(client: nil) ⇒ nil
Clear the cached session for this thread for a client.
-
#client_override ⇒ String | Symbol
Get the global client override.
-
#client_override=(name) ⇒ String | Symbol
Set the global client override.
-
#current_scope(klass = nil) ⇒ Criteria
Get the current Mongoid scope.
-
#current_scope=(scope) ⇒ Criteria
Set the current Mongoid scope.
-
#database_override ⇒ String | Symbol
Get the global database override.
-
#database_override=(name) ⇒ String | Symbol
Set the global database override.
-
#delete(key) ⇒ Object
Removes the named variable from local storage.
-
#execute_callbacks=(flag) ⇒ Object
Indicates whether document callbacks should be invoked by default for the current thread.
-
#execute_callbacks? ⇒ true | false
Queries whether document callbacks should be executed by default for the current thread.
-
#executing?(name) ⇒ true
Are in the middle of executing the named stack.
-
#exit_autosave(document) ⇒ Object
Exit autosaving a document on the current thread.
-
#exit_execution(name) ⇒ true
Exit from a named thread local stack.
-
#exit_validate(document) ⇒ Object
Exit validating a document on the current thread.
-
#exit_without_default_scope(klass) ⇒ Object
private
Exit suppressing default scopes for given model on the current thread.
-
#get(key, &default) ⇒ Object | nil
Queries the thread- or fiber-local variable with the given name.
-
#get_session(client: nil) ⇒ Mongo::Session | nil
Get the cached session for this thread for a client.
-
#has?(key) ⇒ true | false
Queries the presence of a named variable in local storage.
-
#modified_documents ⇒ Hash<Mongo::Session, Set<Mongoid::Document>>
private
Returns the thread store of modified documents.
-
#reset! ⇒ Object
Resets the current thread- or fiber-local storage to its initial state.
-
#sessions ⇒ Hash<Integer, Set>
private
Returns the thread store of sessions.
-
#set(key, value) ⇒ Object
Sets a variable in local storage with the given name to the given value.
-
#set_current_scope(scope, klass) ⇒ Criteria
Set the current Mongoid scope.
-
#set_session(session, client: nil) ⇒ Object
Cache a session for this thread for a client.
-
#stack(name) ⇒ Array
Get the named stack.
-
#validated?(document) ⇒ true | false
Is the document validated on the current thread?.
-
#validations ⇒ Hash
Get all validations on the current thread.
-
#validations_for(klass) ⇒ Array
Get all validations on the current thread for the class.
-
#without_default_scope?(klass) ⇒ Boolean
private
Is the given klass’ default scope suppressed on the current thread?.
Instance Method Details
#add_modified_document(session, document) ⇒ Object
Store a reference to the document that was modified inside a transaction associated with the session.
441 442 443 444 445 |
# File 'lib/mongoid/threaded.rb', line 441 def add_modified_document(session, document) return unless session&.in_transaction? modified_documents[session] << document end |
#autosaved?(document) ⇒ true | false
Is the document autosaved on the current thread?
340 341 342 |
# File 'lib/mongoid/threaded.rb', line 340 def autosaved?(document) autosaves_for(document.class).include?(document._id) end |
#autosaves ⇒ Hash
Get all autosaves on the current thread.
362 363 364 |
# File 'lib/mongoid/threaded.rb', line 362 def autosaves get(AUTOSAVES_KEY) { {} } end |
#autosaves_for(klass) ⇒ Array
Get all autosaves on the current thread for the class.
384 385 386 |
# File 'lib/mongoid/threaded.rb', line 384 def autosaves_for(klass) autosaves[klass] ||= [] end |
#begin_autosave(document) ⇒ Object
Begin autosaving a document on the current thread.
191 192 193 |
# File 'lib/mongoid/threaded.rb', line 191 def begin_autosave(document) autosaves_for(document.class).push(document._id) end |
#begin_execution(name) ⇒ true
Begin entry into a named thread local stack.
123 124 125 |
# File 'lib/mongoid/threaded.rb', line 123 def begin_execution(name) stack(name).push(true) end |
#begin_validate(document) ⇒ Object
Begin validating a document on the current thread.
201 202 203 |
# File 'lib/mongoid/threaded.rb', line 201 def begin_validate(document) validations_for(document.class).push(document._id) end |
#begin_without_default_scope(klass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Begin suppressing default scopes for given model on the current thread.
233 234 235 |
# File 'lib/mongoid/threaded.rb', line 233 def begin_without_default_scope(klass) stack(:without_default_scope).push(klass) end |
#clear_modified_documents(session) ⇒ Set<Mongoid::Document>
Clears the set of modified documents for the given session, and return the content of the set before the clearance.
454 455 456 |
# File 'lib/mongoid/threaded.rb', line 454 def clear_modified_documents(session) modified_documents.delete(session) || [] end |
#clear_session(client: nil) ⇒ nil
For backward compatibility it is allowed to call this method without
Clear the cached session for this thread for a client.
specifying ‘client` parameter.
431 432 433 |
# File 'lib/mongoid/threaded.rb', line 431 def clear_session(client: nil) sessions.delete(client)&.end_session end |
#client_override ⇒ String | Symbol
Get the global client override.
255 256 257 |
# File 'lib/mongoid/threaded.rb', line 255 def client_override get(CLIENT_OVERRIDE_KEY) end |
#client_override=(name) ⇒ String | Symbol
Set the global client override.
267 268 269 |
# File 'lib/mongoid/threaded.rb', line 267 def client_override=(name) set(CLIENT_OVERRIDE_KEY, name) end |
#current_scope(klass = nil) ⇒ Criteria
Get the current Mongoid scope.
280 281 282 283 284 285 286 287 288 |
# File 'lib/mongoid/threaded.rb', line 280 def current_scope(klass = nil) current_scope = get(CURRENT_SCOPE_KEY) if klass && current_scope.respond_to?(:keys) current_scope[current_scope.keys.find { |k| k <= klass }] else current_scope end end |
#current_scope=(scope) ⇒ Criteria
Set the current Mongoid scope.
298 299 300 |
# File 'lib/mongoid/threaded.rb', line 298 def current_scope=(scope) set(CURRENT_SCOPE_KEY, scope) end |
#database_override ⇒ String | Symbol
Get the global database override.
133 134 135 |
# File 'lib/mongoid/threaded.rb', line 133 def database_override get(DATABASE_OVERRIDE_KEY) end |
#database_override=(name) ⇒ String | Symbol
Set the global database override.
145 146 147 |
# File 'lib/mongoid/threaded.rb', line 145 def database_override=(name) set(DATABASE_OVERRIDE_KEY, name) end |
#delete(key) ⇒ Object
Removes the named variable from local storage.
102 103 104 |
# File 'lib/mongoid/threaded.rb', line 102 def delete(key) storage.delete(key) end |
#execute_callbacks=(flag) ⇒ Object
Indicates whether document callbacks should be invoked by default for the current thread. Individual documents may further override the callback behavior, but this will be used for the default behavior.
480 481 482 |
# File 'lib/mongoid/threaded.rb', line 480 def execute_callbacks=(flag) set(EXECUTE_CALLBACKS, flag) end |
#execute_callbacks? ⇒ true | false
Queries whether document callbacks should be executed by default for the current thread.
Unless otherwise indicated (by #execute_callbacks=), this will return true.
466 467 468 469 470 471 472 |
# File 'lib/mongoid/threaded.rb', line 466 def execute_callbacks? if has?(EXECUTE_CALLBACKS) get(EXECUTE_CALLBACKS) else true end end |
#executing?(name) ⇒ true
Are in the middle of executing the named stack
157 158 159 |
# File 'lib/mongoid/threaded.rb', line 157 def executing?(name) !stack(name).empty? end |
#exit_autosave(document) ⇒ Object
Exit autosaving a document on the current thread.
211 212 213 |
# File 'lib/mongoid/threaded.rb', line 211 def exit_autosave(document) autosaves_for(document.class).delete_one(document._id) end |
#exit_execution(name) ⇒ true
Exit from a named thread local stack.
169 170 171 |
# File 'lib/mongoid/threaded.rb', line 169 def exit_execution(name) stack(name).pop end |
#exit_validate(document) ⇒ Object
Exit validating a document on the current thread.
221 222 223 |
# File 'lib/mongoid/threaded.rb', line 221 def exit_validate(document) validations_for(document.class).delete_one(document._id) end |
#exit_without_default_scope(klass) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Exit suppressing default scopes for given model on the current thread.
245 246 247 |
# File 'lib/mongoid/threaded.rb', line 245 def exit_without_default_scope(klass) stack(:without_default_scope).delete(klass) end |
#get(key, &default) ⇒ Object | nil
Queries the thread- or fiber-local variable with the given name. If a block is given, and the variable does not already exist, the return value of the block will be set as the value of the variable before returning it.
It is very important that applications (and especially Mongoid) use this method instead of Thread#[], since Thread#[] is actually for fiber-local variables, and Mongoid uses Fibers as an implementation detail in some callbacks. Putting thread-local state in a fiber-local store will result in the state being invisible when relevant callbacks are run in a different fiber.
Affected callbacks are cascading callbacks on embedded children.
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/mongoid/threaded.rb', line 77 def get(key, &default) result = storage[key] if result.nil? && default result = yield set(key, result) end result end |
#get_session(client: nil) ⇒ Mongo::Session | nil
For backward compatibility it is allowed to call this method without
Get the cached session for this thread for a client.
specifying ‘client` parameter.
419 420 421 |
# File 'lib/mongoid/threaded.rb', line 419 def get_session(client: nil) sessions[client] end |
#has?(key) ⇒ true | false
Queries the presence of a named variable in local storage.
111 112 113 |
# File 'lib/mongoid/threaded.rb', line 111 def has?(key) storage.key?(key) end |
#modified_documents ⇒ Hash<Mongo::Session, Set<Mongoid::Document>>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the thread store of modified documents.
499 500 501 |
# File 'lib/mongoid/threaded.rb', line 499 def modified_documents get(MODIFIED_DOCUMENTS_KEY) { Hash.new { |h, k| h[k] = Set.new } } end |
#reset! ⇒ Object
Resets the current thread- or fiber-local storage to its initial state. This is useful for making sure the state is clean when starting a new thread or fiber.
The value of Mongoid::Config.real_isolation_level is used to determine whether to reset the storage for the current thread or fiber.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/mongoid/threaded.rb', line 47 def reset! case Config.real_isolation_level when :thread Thread.current.thread_variable_set(STORAGE_KEY, nil) when :fiber Fiber[STORAGE_KEY] = nil else raise "Unknown isolation level: #{Config.real_isolation_level.inspect}" end end |
#sessions ⇒ Hash<Integer, Set>
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the thread store of sessions.
489 490 491 |
# File 'lib/mongoid/threaded.rb', line 489 def sessions get(SESSIONS_KEY) { {}.compare_by_identity } end |
#set(key, value) ⇒ Object
Sets a variable in local storage with the given name to the given value. See #get for a discussion of why this method is necessary, and why Thread#[]= should be avoided in cascading callbacks on embedded children.
95 96 97 |
# File 'lib/mongoid/threaded.rb', line 95 def set(key, value) storage[key] = value end |
#set_current_scope(scope, klass) ⇒ Criteria
Set the current Mongoid scope. Safe for multi-model scope chaining.
311 312 313 314 315 316 317 318 |
# File 'lib/mongoid/threaded.rb', line 311 def set_current_scope(scope, klass) if scope.nil? unset_current_scope(klass) else current_scope = get(CURRENT_SCOPE_KEY) { {} } current_scope[klass] = scope end end |
#set_session(session, client: nil) ⇒ Object
For backward compatibility it is allowed to call this method without
Cache a session for this thread for a client.
specifying ‘client` parameter.
407 408 409 |
# File 'lib/mongoid/threaded.rb', line 407 def set_session(session, client: nil) sessions[client] = session end |
#stack(name) ⇒ Array
Get the named stack.
181 182 183 |
# File 'lib/mongoid/threaded.rb', line 181 def stack(name) get(STACK_KEYS[name]) { [] } end |
#validated?(document) ⇒ true | false
Is the document validated on the current thread?
352 353 354 |
# File 'lib/mongoid/threaded.rb', line 352 def validated?(document) validations_for(document.class).include?(document._id) end |
#validations ⇒ Hash
Get all validations on the current thread.
372 373 374 |
# File 'lib/mongoid/threaded.rb', line 372 def validations get(VALIDATIONS_KEY) { {} } end |
#validations_for(klass) ⇒ Array
Get all validations on the current thread for the class.
396 397 398 |
# File 'lib/mongoid/threaded.rb', line 396 def validations_for(klass) validations[klass] ||= [] end |
#without_default_scope?(klass) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Is the given klass’ default scope suppressed on the current thread?
328 329 330 |
# File 'lib/mongoid/threaded.rb', line 328 def without_default_scope?(klass) stack(:without_default_scope).include?(klass) end |