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
- DATABASE_OVERRIDE_KEY =
'[mongoid]:db-override'
- CLIENTS_KEY =
Constant for the key to store clients.
'[mongoid]:clients'
- CLIENT_OVERRIDE_KEY =
The key to override the client.
'[mongoid]:client-override'
- CURRENT_SCOPE_KEY =
The key for the current thread’s scope stack.
'[mongoid]:current-scope'
- AUTOSAVES_KEY =
'[mongoid]:autosaves'
- VALIDATIONS_KEY =
'[mongoid]:validations'
- STACK_KEYS =
Hash.new do |hash, key| hash[key] = "[mongoid]:#{key}-stack" end
- SESSIONS_KEY =
The key for the current thread’s sessions.
'[mongoid]:sessions'
- MODIFIED_DOCUMENTS_KEY =
The key for storing documents modified inside transactions.
'[mongoid]:modified-documents'
- EXECUTE_CALLBACKS =
The key storing the default value for whether or not callbacks are executed on documents.
'[mongoid]: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 thread-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-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 thread-local storage.
-
#modified_documents ⇒ Hash<Mongo::Session, Set<Mongoid::Document>>
private
Returns the thread store of modified documents.
-
#sessions ⇒ Hash<Integer, Set>
private
Returns the thread store of sessions.
-
#set(key, value) ⇒ Object
Sets a thread-local variable 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.
435 436 437 438 439 |
# File 'lib/mongoid/threaded.rb', line 435 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?
334 335 336 |
# File 'lib/mongoid/threaded.rb', line 334 def autosaved?(document) autosaves_for(document.class).include?(document._id) end |
#autosaves ⇒ Hash
Get all autosaves on the current thread.
356 357 358 |
# File 'lib/mongoid/threaded.rb', line 356 def autosaves get(AUTOSAVES_KEY) { {} } end |
#autosaves_for(klass) ⇒ Array
Get all autosaves on the current thread for the class.
378 379 380 |
# File 'lib/mongoid/threaded.rb', line 378 def autosaves_for(klass) autosaves[klass] ||= [] end |
#begin_autosave(document) ⇒ Object
Begin autosaving a document on the current thread.
185 186 187 |
# File 'lib/mongoid/threaded.rb', line 185 def begin_autosave(document) autosaves_for(document.class).push(document._id) end |
#begin_execution(name) ⇒ true
Begin entry into a named thread local stack.
117 118 119 |
# File 'lib/mongoid/threaded.rb', line 117 def begin_execution(name) stack(name).push(true) end |
#begin_validate(document) ⇒ Object
Begin validating a document on the current thread.
195 196 197 |
# File 'lib/mongoid/threaded.rb', line 195 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.
227 228 229 |
# File 'lib/mongoid/threaded.rb', line 227 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.
448 449 450 |
# File 'lib/mongoid/threaded.rb', line 448 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.
425 426 427 |
# File 'lib/mongoid/threaded.rb', line 425 def clear_session(client: nil) sessions.delete(client)&.end_session end |
#client_override ⇒ String | Symbol
Get the global client override.
249 250 251 |
# File 'lib/mongoid/threaded.rb', line 249 def client_override get(CLIENT_OVERRIDE_KEY) end |
#client_override=(name) ⇒ String | Symbol
Set the global client override.
261 262 263 |
# File 'lib/mongoid/threaded.rb', line 261 def client_override=(name) set(CLIENT_OVERRIDE_KEY, name) end |
#current_scope(klass = nil) ⇒ Criteria
Get the current Mongoid scope.
274 275 276 277 278 279 280 281 282 |
# File 'lib/mongoid/threaded.rb', line 274 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.
292 293 294 |
# File 'lib/mongoid/threaded.rb', line 292 def current_scope=(scope) set(CURRENT_SCOPE_KEY, scope) end |
#database_override ⇒ String | Symbol
Get the global database override.
127 128 129 |
# File 'lib/mongoid/threaded.rb', line 127 def database_override get(DATABASE_OVERRIDE_KEY) end |
#database_override=(name) ⇒ String | Symbol
Set the global database override.
139 140 141 |
# File 'lib/mongoid/threaded.rb', line 139 def database_override=(name) set(DATABASE_OVERRIDE_KEY, name) end |
#delete(key) ⇒ Object
Removes the named variable from thread-local storage.
84 85 86 |
# File 'lib/mongoid/threaded.rb', line 84 def delete(key) set(key, nil) 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.
474 475 476 |
# File 'lib/mongoid/threaded.rb', line 474 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.
460 461 462 463 464 465 466 |
# File 'lib/mongoid/threaded.rb', line 460 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
151 152 153 |
# File 'lib/mongoid/threaded.rb', line 151 def executing?(name) !stack(name).empty? end |
#exit_autosave(document) ⇒ Object
Exit autosaving a document on the current thread.
205 206 207 |
# File 'lib/mongoid/threaded.rb', line 205 def exit_autosave(document) autosaves_for(document.class).delete_one(document._id) end |
#exit_execution(name) ⇒ true
Exit from a named thread local stack.
163 164 165 |
# File 'lib/mongoid/threaded.rb', line 163 def exit_execution(name) stack(name).pop end |
#exit_validate(document) ⇒ Object
Exit validating a document on the current thread.
215 216 217 |
# File 'lib/mongoid/threaded.rb', line 215 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.
239 240 241 |
# File 'lib/mongoid/threaded.rb', line 239 def exit_without_default_scope(klass) stack(:without_default_scope).delete(klass) end |
#get(key, &default) ⇒ Object | nil
Queries the thread-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 espcially 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.
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/mongoid/threaded.rb', line 59 def get(key, &default) result = Thread.current.thread_variable_get(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.
413 414 415 |
# File 'lib/mongoid/threaded.rb', line 413 def get_session(client: nil) sessions[client] end |
#has?(key) ⇒ true | false
Queries the presence of a named variable in thread-local storage.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/mongoid/threaded.rb', line 93 def has?(key) # Here we have a classic example of JRuby not behaving like MRI. In # MRI, if you set a thread variable to nil, it removes it from the list # and subsequent calls to thread_variable?(key) will return false. Not # so with JRuby. Once set, you cannot unset the thread variable. # # However, because setting a variable to nil is supposed to remove it, # we can assume a nil-valued variable doesn't actually exist. # So, instead of this: # Thread.current.thread_variable?(key) # We have to do this: !get(key).nil? 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.
493 494 495 |
# File 'lib/mongoid/threaded.rb', line 493 def modified_documents get(MODIFIED_DOCUMENTS_KEY) { Hash.new { |h, k| h[k] = Set.new } } 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.
483 484 485 |
# File 'lib/mongoid/threaded.rb', line 483 def sessions get(SESSIONS_KEY) { {}.compare_by_identity } end |
#set(key, value) ⇒ Object
Sets a thread-local variable 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.
77 78 79 |
# File 'lib/mongoid/threaded.rb', line 77 def set(key, value) Thread.current.thread_variable_set(key, value) end |
#set_current_scope(scope, klass) ⇒ Criteria
Set the current Mongoid scope. Safe for multi-model scope chaining.
305 306 307 308 309 310 311 312 |
# File 'lib/mongoid/threaded.rb', line 305 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.
401 402 403 |
# File 'lib/mongoid/threaded.rb', line 401 def set_session(session, client: nil) sessions[client] = session end |
#stack(name) ⇒ Array
Get the named stack.
175 176 177 |
# File 'lib/mongoid/threaded.rb', line 175 def stack(name) get(STACK_KEYS[name]) { [] } end |
#validated?(document) ⇒ true | false
Is the document validated on the current thread?
346 347 348 |
# File 'lib/mongoid/threaded.rb', line 346 def validated?(document) validations_for(document.class).include?(document._id) end |
#validations ⇒ Hash
Get all validations on the current thread.
366 367 368 |
# File 'lib/mongoid/threaded.rb', line 366 def validations get(VALIDATIONS_KEY) { {} } end |
#validations_for(klass) ⇒ Array
Get all validations on the current thread for the class.
390 391 392 |
# File 'lib/mongoid/threaded.rb', line 390 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?
322 323 324 |
# File 'lib/mongoid/threaded.rb', line 322 def without_default_scope?(klass) stack(:without_default_scope).include?(klass) end |