Module: Sidekiq::TransactionGuard
- Defined in:
- lib/sidekiq/transaction_guard.rb,
lib/sidekiq/transaction_guard/railtie.rb,
lib/sidekiq/transaction_guard/version.rb,
lib/sidekiq/transaction_guard/minitest.rb,
lib/sidekiq/transaction_guard/middleware.rb,
lib/sidekiq/transaction_guard/database_cleaner.rb
Defined Under Namespace
Modules: DatabaseCleaner, MinitestHelper Classes: InsideTransactionError, Middleware, Railtie
Constant Summary collapse
- VALID_MODES =
[:warn, :stderr, :error, :disabled].freeze
- VERSION =
File.read(File.("../../../../VERSION", __FILE__)).chomp.freeze
Class Attribute Summary collapse
-
.mode ⇒ Symbol
Return the current mode.
Class Method Summary collapse
-
.add_connection_class(connection_class) ⇒ void
Add a class that maintains its own connection pool to the connections being monitored for open transactions.
-
.connection_classes ⇒ Array<Class>
Return the classes that have been added via ‘add_connection_class`.
-
.disable { ... } ⇒ Object
Disable the transaction guard within the provided block.
-
.in_transaction? ⇒ Boolean
Return true if any connection is currently inside of a transaction.
-
.init(mode: nil) ⇒ void
Helper method to add the client middleware to Sidekiq.
-
.notify {|Hash| ... } ⇒ void
Define the global notify block.
-
.notify_block ⇒ Proc?
Return the block set as the notify handler with a call to ‘notify`.
-
.set_allowed_transaction_level(connection_classes, base_transaction_level = 0) ⇒ void
This method needs to be called to set the allowed transaction level for a connection class (see ‘add_connection_class` for more info).
-
.testing { ... } ⇒ Object
This method call needs to be wrapped around tests that use transactional fixtures.
Class Attribute Details
.mode ⇒ Symbol
Return the current mode.
58 59 60 |
# File 'lib/sidekiq/transaction_guard.rb', line 58 def mode @mode end |
Class Method Details
.add_connection_class(connection_class) ⇒ void
This method returns an undefined value.
Add a class that maintains its own connection pool to the connections being monitored for open transactions. You don’t need to add ‘ActiveRecord::Base` or subclasses. Only the base class that establishes a new connection pool with a call to `establish_connection` needs to be added.
84 85 86 |
# File 'lib/sidekiq/transaction_guard.rb', line 84 def add_connection_class(connection_class) @lock.synchronize { @connection_classes << connection_class } end |
.connection_classes ⇒ Array<Class>
Return the classes that have been added via ‘add_connection_class`.
91 92 93 |
# File 'lib/sidekiq/transaction_guard.rb', line 91 def connection_classes ([ActiveRecord::Base] + @lock.synchronize { @connection_classes.to_a }).uniq end |
.disable { ... } ⇒ Object
Disable the transaction guard within the provided block. This is useful in test environments when you want to setup data for your tests without worrying about transaction levels.
115 116 117 118 119 120 121 122 123 |
# File 'lib/sidekiq/transaction_guard.rb', line 115 def disable save_mode = mode begin self.mode = :disabled yield ensure self.mode = save_mode end end |
.in_transaction? ⇒ Boolean
Return true if any connection is currently inside of a transaction.
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/sidekiq/transaction_guard.rb', line 98 def in_transaction? connection_classes.any? do |connection_class| connection_pool = connection_class.connection_pool connection = connection_class.connection if connection_pool.active_connection? if connection connection.open_transactions > allowed_transaction_level(connection_class) else false end end end |
.init(mode: nil) ⇒ void
This method returns an undefined value.
Helper method to add the client middleware to Sidekiq.
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/sidekiq/transaction_guard.rb', line 25 def init(mode: nil) self.mode = mode if mode Sidekiq.configure_client do |config| config.client_middleware do |chain| unless chain.exists?(Sidekiq::TransactionGuard::Middleware) chain.add Sidekiq::TransactionGuard::Middleware end end end end |
.notify {|Hash| ... } ⇒ void
This method returns an undefined value.
Define the global notify block. This block will be called with a Sidekiq job hash for all jobs enqueued inside transactions if the mode is ‘:warn` or `:stderr`.
66 67 68 |
# File 'lib/sidekiq/transaction_guard.rb', line 66 def notify(&block) @notify = block end |
.notify_block ⇒ Proc?
Return the block set as the notify handler with a call to ‘notify`.
73 74 75 |
# File 'lib/sidekiq/transaction_guard.rb', line 73 def notify_block @notify end |
.set_allowed_transaction_level(connection_classes, base_transaction_level = 0) ⇒ void
This method returns an undefined value.
This method needs to be called to set the allowed transaction level for a connection class (see ‘add_connection_class` for more info). The current transaction level for that class’s connection will be set as the zero point. This method can only be called inside a block wrapped with the ‘testing` method.
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/sidekiq/transaction_guard.rb', line 156 def set_allowed_transaction_level(connection_classes, base_transaction_level = 0) connection_counts = Thread.current[:sidekiq_rails_transaction_guard] unless connection_counts raise("set_allowed_transaction_level is only allowed inside a testing block") end connection_classes = self.connection_classes if connection_classes == :all Array(connection_classes).each do |connection_class| class_count = connection_class.connection.open_transactions + base_transaction_level connection_counts[connection_class.name] = class_count end end |
.testing { ... } ⇒ Object
This method call needs to be wrapped around tests that use transactional fixtures. It sets up data structures used to track the number of open transactions. The current transaction level is automatically captured as the baseline so that any transactions opened by test setup (e.g. transactional fixtures) are ignored.
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/sidekiq/transaction_guard.rb', line 132 def testing var = :sidekiq_rails_transaction_guard save_val = Thread.current[var] begin Thread.current[var] = (save_val ? save_val.dup : {}) set_allowed_transaction_level(:all) yield ensure Thread.current[var] = save_val end end |