Class: RaceGuard::Context::MutableStore
- Inherits:
-
Object
- Object
- RaceGuard::Context::MutableStore
- Defined in:
- lib/race_guard/context.rb
Overview
Mutable per-thread store (never shared across threads).
Constant Summary collapse
- RMW_TTL_SEC =
DBLockAuditor::ReadModifyWrite (Epic 4.1) — bounded RMW read journal
2.0- RMW_MAX_ENTRIES =
500
Instance Attribute Summary collapse
-
#protected_blocks ⇒ Object
readonly
Returns the value of attribute protected_blocks.
-
#transaction_depth ⇒ Object
readonly
Returns the value of attribute transaction_depth.
Instance Method Summary collapse
- #begin_transaction ⇒ Object
- #defer_after_commit(proc) ⇒ Object
- #end_transaction(success: true) ⇒ Object
-
#initialize ⇒ MutableStore
constructor
A new instance of MutableStore.
- #pop_protected ⇒ Object
- #push_protected(name) ⇒ Object
- #rmw_pessimistic_lock_active?(model_class, record_id) ⇒ Boolean
- #rmw_pessimistic_lock_register!(model_class, record_id) ⇒ Object
- #rmw_read_age_ms_for(model_class, record_id, attr_name) ⇒ Object
- #rmw_read_forget!(model_class, record_id, attr_name) ⇒ Object
- #rmw_read_forget_record!(model_class, record_id) ⇒ Object
- #rmw_read_record!(model_class, record_id, attr_name) ⇒ Object
Constructor Details
#initialize ⇒ MutableStore
Returns a new instance of MutableStore.
144 145 146 147 148 149 150 |
# File 'lib/race_guard/context.rb', line 144 def initialize @transaction_depth = 0 @protected_blocks = [] @after_commit_stack = [] @rmw_last_read_at = {} @rmw_pessimistic_lock_rows = Set.new end |
Instance Attribute Details
#protected_blocks ⇒ Object (readonly)
Returns the value of attribute protected_blocks.
182 183 184 |
# File 'lib/race_guard/context.rb', line 182 def protected_blocks @protected_blocks end |
#transaction_depth ⇒ Object (readonly)
Returns the value of attribute transaction_depth.
182 183 184 |
# File 'lib/race_guard/context.rb', line 182 def transaction_depth @transaction_depth end |
Instance Method Details
#begin_transaction ⇒ Object
160 161 162 163 |
# File 'lib/race_guard/context.rb', line 160 def begin_transaction @transaction_depth += 1 @after_commit_stack << [] end |
#defer_after_commit(proc) ⇒ Object
174 175 176 177 178 179 180 |
# File 'lib/race_guard/context.rb', line 174 def defer_after_commit(proc) if @after_commit_stack.empty? run_after_commit_proc(proc) else @after_commit_stack.last << proc end end |
#end_transaction(success: true) ⇒ Object
165 166 167 168 169 170 171 172 |
# File 'lib/race_guard/context.rb', line 165 def end_transaction(success: true) return unless @transaction_depth.positive? callbacks = @after_commit_stack.pop @transaction_depth -= 1 flush_after_commit_callbacks(callbacks, success) @rmw_pessimistic_lock_rows.clear if @transaction_depth.zero? end |
#pop_protected ⇒ Object
156 157 158 |
# File 'lib/race_guard/context.rb', line 156 def pop_protected @protected_blocks.pop end |
#push_protected(name) ⇒ Object
152 153 154 |
# File 'lib/race_guard/context.rb', line 152 def push_protected(name) @protected_blocks << name.to_sym end |
#rmw_pessimistic_lock_active?(model_class, record_id) ⇒ Boolean
222 223 224 |
# File 'lib/race_guard/context.rb', line 222 def rmw_pessimistic_lock_active?(model_class, record_id) @rmw_pessimistic_lock_rows.include?([model_class.object_id, record_id]) end |
#rmw_pessimistic_lock_register!(model_class, record_id) ⇒ Object
217 218 219 220 |
# File 'lib/race_guard/context.rb', line 217 def rmw_pessimistic_lock_register!(model_class, record_id) @rmw_pessimistic_lock_rows << [model_class.object_id, record_id] self end |
#rmw_read_age_ms_for(model_class, record_id, attr_name) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/race_guard/context.rb', line 193 def rmw_read_age_ms_for(model_class, record_id, attr_name) name = attr_name.to_s now = monotonic_time_ms key = rmw_key(model_class, record_id, name) prune_stale_rmw_map!(now) t = @rmw_last_read_at[key] return nil unless t return nil if (now - t) > (RMW_TTL_SEC * 1000.0) (now - t) end |
#rmw_read_forget!(model_class, record_id, attr_name) ⇒ Object
205 206 207 208 209 |
# File 'lib/race_guard/context.rb', line 205 def rmw_read_forget!(model_class, record_id, attr_name) key = rmw_key(model_class, record_id, attr_name.to_s) @rmw_last_read_at.delete(key) self end |
#rmw_read_forget_record!(model_class, record_id) ⇒ Object
211 212 213 214 215 |
# File 'lib/race_guard/context.rb', line 211 def rmw_read_forget_record!(model_class, record_id) oid = model_class.object_id @rmw_last_read_at.delete_if { |k, _| k[0] == oid && k[1] == record_id } self end |
#rmw_read_record!(model_class, record_id, attr_name) ⇒ Object
184 185 186 187 188 189 190 191 |
# File 'lib/race_guard/context.rb', line 184 def rmw_read_record!(model_class, record_id, attr_name) name = attr_name.to_s now = monotonic_time_ms key = rmw_key(model_class, record_id, name) prune_stale_rmw_map!(now) @rmw_last_read_at[key] = now evict_oldest_rmw_reads_if_needed! end |