Module: Isolator
- Extended by:
- Callbacks, Isolate
- Defined in:
- lib/isolator.rb,
lib/isolator/errors.rb,
lib/isolator/ignorer.rb,
lib/isolator/isolate.rb,
lib/isolator/railtie.rb,
lib/isolator/version.rb,
lib/isolator/notifier.rb,
lib/isolator/callbacks.rb,
lib/isolator/adapters/base.rb,
lib/isolator/configuration.rb,
lib/isolator/simple_hashie.rb,
lib/isolator/adapter_builder.rb,
lib/isolator/ext/thread_fetch.rb,
lib/isolator/plugins/database_subtransactions.rb,
lib/isolator/orm_adapters/active_support_subscriber.rb,
lib/isolator/plugins/concurrent_database_transactions.rb,
lib/isolator/orm_adapters/active_support_transaction_subscriber.rb
Overview
Defined Under Namespace
Modules: ActiveSupportSubscriber, ActiveSupportTransactionSubscriber, AdapterBuilder, Adapters, Callbacks, Isolate, ThreadFetch
Classes: BackgroundJobError, ConcurrentTransactionError, Configuration, HTTPError, Ignorer, MailerError, MaxSubtransactionsExceededError, Notifier, Railtie, SimpleHashie, ThreadStateProxy, UnsafeOperationError, WebsocketError
Constant Summary
collapse
- VERSION =
"1.2.0"
Class Attribute Summary collapse
Class Method Summary
collapse
Methods included from Callbacks
after_isolate, after_isolate_callbacks, before_isolate, before_isolate_callbacks, finish!, notify!, on_transaction_begin, on_transaction_end, start!, transaction_begin_callbacks, transaction_end_callbacks
Methods included from Isolate
isolate, remove_adapter
Class Attribute Details
.backtrace_cleaner ⇒ Object
Returns the value of attribute backtrace_cleaner.
212
213
214
|
# File 'lib/isolator.rb', line 212
def backtrace_cleaner
@backtrace_cleaner
end
|
.backtrace_length ⇒ Object
Returns the value of attribute backtrace_length.
212
213
214
|
# File 'lib/isolator.rb', line 212
def backtrace_length
@backtrace_length
end
|
.debug_enabled ⇒ Object
Returns the value of attribute debug_enabled.
212
213
214
|
# File 'lib/isolator.rb', line 212
def debug_enabled
@debug_enabled
end
|
.default_connection_id ⇒ Object
Returns the value of attribute default_connection_id.
37
38
39
|
# File 'lib/isolator.rb', line 37
def default_connection_id
@default_connection_id
end
|
.default_threshold ⇒ Object
Returns the value of attribute default_threshold.
37
38
39
|
# File 'lib/isolator.rb', line 37
def default_threshold
@default_threshold
end
|
Class Method Details
.adapters ⇒ Object
196
197
198
|
# File 'lib/isolator.rb', line 196
def adapters
@adapters ||= Isolator::SimpleHashie.new
end
|
.all_transactions ⇒ Object
97
98
99
|
# File 'lib/isolator.rb', line 97
def all_transactions
state[:transactions] || {}
end
|
.clear_transactions! ⇒ Object
177
178
179
|
# File 'lib/isolator.rb', line 177
def clear_transactions!
state[:transactions]&.clear
end
|
.config ⇒ Object
39
40
41
|
# File 'lib/isolator.rb', line 39
def config
@config ||= Configuration.new
end
|
43
44
45
|
# File 'lib/isolator.rb', line 43
def configure
yield config
end
|
.connection_threshold(connection_id) ⇒ Object
101
102
103
|
# File 'lib/isolator.rb', line 101
def connection_threshold(connection_id)
state[:thresholds]&.[](connection_id) || default_threshold
end
|
.current_transactions(connection_id = default_connection_id.call) ⇒ Object
93
94
95
|
# File 'lib/isolator.rb', line 93
def current_transactions(connection_id = default_connection_id.call)
state[:transactions]&.[](connection_id) || 0
end
|
.decr_thresholds! ⇒ Object
121
122
123
124
125
126
127
128
|
# File 'lib/isolator.rb', line 121
def decr_thresholds!
self.default_threshold -= 1
debug!("Thresholds were incremented")
return unless state[:thresholds]
state[:thresholds].transform_values!(&:pred)
end
|
.decr_transactions!(connection_id = default_connection_id.call) ⇒ Object
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
# File 'lib/isolator.rb', line 152
def decr_transactions!(connection_id = default_connection_id.call)
current = state[:transactions]&.[](connection_id) || 0
if current <= 0
warn "Trying to finalize an untracked transaction"
return
end
state[:transactions][connection_id] -= 1
current_depth = current_transactions(connection_id)
threshold = connection_threshold(connection_id)
if current_depth >= threshold - 1
event = {connection_id: connection_id, depth: current_depth - threshold + 1}.freeze
notify!(:end, event)
end
finish! if current_depth == (threshold - 1)
state[:transactions].delete(connection_id) if state[:transactions][connection_id].zero?
debug!("Transaction closed for connection #{connection_id} (total: #{state[:transactions][connection_id]}, threshold: #{state[:thresholds]&.[](connection_id) || default_threshold})")
end
|
.disable ⇒ Object
Accepts block and disable Isolator within
60
61
62
63
64
65
66
67
68
69
70
|
# File 'lib/isolator.rb', line 60
def disable
return yield if disabled?
res = nil
begin
disable!
res = yield
ensure
enable!
end
res
end
|
.disable! ⇒ Object
55
56
57
|
# File 'lib/isolator.rb', line 55
def disable!
state[:disabled] = true
end
|
.disabled? ⇒ Boolean
192
193
194
|
# File 'lib/isolator.rb', line 192
def disabled?
state[:disabled] == true
end
|
.enable ⇒ Object
Accepts block and enable Isolator within
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/isolator.rb', line 73
def enable
return yield if enabled?
res = nil
begin
enable!
res = yield
ensure
disable!
end
res
end
|
.enable! ⇒ Object
51
52
53
|
# File 'lib/isolator.rb', line 51
def enable!
state[:disabled] = false
end
|
.enabled? ⇒ Boolean
188
189
190
|
# File 'lib/isolator.rb', line 188
def enabled?
!disabled?
end
|
.has_adapter?(id) ⇒ Boolean
200
201
202
|
# File 'lib/isolator.rb', line 200
def has_adapter?(id)
adapters.key?(id.to_s)
end
|
.incr_thresholds! ⇒ Object
112
113
114
115
116
117
118
119
|
# File 'lib/isolator.rb', line 112
def incr_thresholds!
self.default_threshold += 1
debug!("Thresholds were incremented")
return unless state[:thresholds]
state[:thresholds].transform_values!(&:succ)
end
|
.incr_transactions!(connection_id = default_connection_id.call) ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/isolator.rb', line 130
def incr_transactions!(connection_id = default_connection_id.call)
state[:transactions] ||= Hash.new { |h, k| h[k] = 0 }
state[:transactions][connection_id] += 1
pending_threshold = state[:thresholds]&.delete(0)
if pending_threshold
state[:thresholds][connection_id] = pending_threshold
end
debug!("Transaction opened for connection #{connection_id} (total: #{state[:transactions][connection_id]}, threshold: #{state[:thresholds]&.fetch(connection_id, default_threshold)})")
current_depth = current_transactions(connection_id)
threshold = connection_threshold(connection_id)
start! if current_depth == threshold
if current_depth >= threshold
event = {connection_id: connection_id, depth: current_depth - threshold + 1}.freeze
notify!(:begin, event)
end
end
|
.load_ignore_config(path) ⇒ Object
204
205
206
207
|
# File 'lib/isolator.rb', line 204
def load_ignore_config(path)
warn "[DEPRECATION] `load_ignore_config` is deprecated. Please use `Isolator::Ignorer.prepare` instead."
Isolator::Ignorer.prepare(path: path)
end
|
.notify(exception:, backtrace:) ⇒ Object
47
48
49
|
# File 'lib/isolator.rb', line 47
def notify(exception:, backtrace:)
Notifier.new(exception, backtrace).call
end
|
.set_connection_threshold(val, connection_id = default_connection_id.call) ⇒ Object
105
106
107
108
109
110
|
# File 'lib/isolator.rb', line 105
def set_connection_threshold(val, connection_id = default_connection_id.call)
state[:thresholds] ||= Hash.new { |h, k| h[k] = Isolator.default_threshold }
state[:thresholds][connection_id] = val
debug!("Threshold value was changed for connection #{connection_id}: #{val}")
end
|
.transactions_threshold(connection_id = default_connection_id.call) ⇒ Object
89
90
91
|
# File 'lib/isolator.rb', line 89
def transactions_threshold(connection_id = default_connection_id.call)
connection_threshold(connection_id)
end
|
.transactions_threshold=(val) ⇒ Object
85
86
87
|
# File 'lib/isolator.rb', line 85
def transactions_threshold=(val)
set_connection_threshold(val)
end
|
.within_transaction? ⇒ Boolean
181
182
183
184
185
186
|
# File 'lib/isolator.rb', line 181
def within_transaction?
state[:transactions]&.each do |connection_id, transaction_count|
return true if transaction_count >= connection_threshold(connection_id)
end
false
end
|