Module: SidekiqTransactionGuard

Defined in:
lib/sidekiq_transaction_guard.rb,
lib/sidekiq_transaction_guard/version.rb,
lib/sidekiq_transaction_guard/middleware.rb,
lib/sidekiq_transaction_guard/database_cleaner.rb

Defined Under Namespace

Modules: DatabaseCleaner Classes: InsideTransactionError, Middleware

Constant Summary collapse

VALID_MODES =
[:warn, :stderr, :error, :disabled].freeze
VERSION =
File.read(File.expand_path("../../../VERSION", __FILE__)).chomp.freeze

Class Method Summary collapse

Class Method Details

.add_connection_class(connection_class) ⇒ Object

Add a class that maintains it's 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.


55
56
57
58
# File 'lib/sidekiq_transaction_guard.rb', line 55

def add_connection_class(connection_class)
  @connection_classes ||= Set.new
  @connection_classes << connection_class
end

.in_transaction?Boolean

Return true if any connection is currently inside of a transaction.


61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/sidekiq_transaction_guard.rb', line 61

def in_transaction?
  connection_classes = @lock.synchronize{ @connection_classes.dup }
  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

.modeObject

Return the current mode.


35
36
37
# File 'lib/sidekiq_transaction_guard.rb', line 35

def mode
  @mode
end

.mode=(symbol) ⇒ Object

Set the global mode to one of `[:warn, :stderr, :error, :disabled]`. The default mode is `:warn`. This controls the behavior of workers enqueued inside of transactions.

  • :warn - Log to Sidekiq.logger

  • :stderr - Log to $stderr

  • :error - Throw a `SidekiqTransactionGuard::InsideTransactionError`

  • :disabled - Allow workers inside of transactions


26
27
28
29
30
31
32
# File 'lib/sidekiq_transaction_guard.rb', line 26

def mode=(symbol)
  if VALID_MODES.include?(symbol)
    @mode = symbol
  else
    raise ArgumentError.new("mode must be one of #{VALID_MODES.inspect}")
  end
end

.notify(&block) ⇒ Object

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`.


42
43
44
# File 'lib/sidekiq_transaction_guard.rb', line 42

def notify(&block)
  @notify = block
end

.notify_blockObject

Return the block set as the notify handler with a call to `notify`.


47
48
49
# File 'lib/sidekiq_transaction_guard.rb', line 47

def notify_block
  @notify ||= nil
end

.set_allowed_transaction_level(connection_class) ⇒ Object

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' connection will be set as the zero point. This method can only be called inside a block wrapped with the `testing` method.


91
92
93
94
95
96
97
# File 'lib/sidekiq_transaction_guard.rb', line 91

def set_allowed_transaction_level(connection_class)
  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_counts[connection_class.name] = connection_class.connection.open_transactions if connection_counts
end

.testing(&block) ⇒ 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.


76
77
78
79
80
81
82
83
84
85
# File 'lib/sidekiq_transaction_guard.rb', line 76

def testing(&block)
  var = :sidekiq_rails_transaction_guard
  save_val = Thread.current[var]
  begin
    Thread.current[var] = (save_val ? save_val.dup : {})
    yield
  ensure
    Thread.current[var] = save_val
  end
end