Module: RaceGuard

Defined in:
lib/race_guard/distributed/redis_lock_store.rb,
lib/race_guard.rb,
lib/race_guard/rule.rb,
lib/race_guard/event.rb,
lib/race_guard/context.rb,
lib/race_guard/version.rb,
lib/race_guard/constants.rb,
lib/race_guard/protection.rb,
lib/race_guard/rule_engine.rb,
lib/race_guard/interceptors.rb,
lib/race_guard/method_watch.rb,
lib/race_guard/shared_state.rb,
lib/race_guard/active_record.rb,
lib/race_guard/configuration.rb,
lib/race_guard/detector_runtime.rb,
lib/race_guard/method_resolution.rb,
lib/race_guard/distributed/runner.rb,
lib/race_guard/report_raised_error.rb,
lib/race_guard/interceptors/emitter.rb,
lib/race_guard/interceptors/faraday.rb,
lib/race_guard/shared_state/watcher.rb,
lib/race_guard/commit_safety/watcher.rb,
lib/race_guard/interceptors/net_http.rb,
lib/race_guard/distributed/lock_store.rb,
lib/race_guard/index_integrity/runner.rb,
lib/race_guard/reporters/log_reporter.rb,
lib/race_guard/distributed/key_builder.rb,
lib/race_guard/interceptors/active_job.rb,
lib/race_guard/reporters/file_reporter.rb,
lib/race_guard/reporters/json_reporter.rb,
lib/race_guard/shared_state/mutex_stack.rb,
lib/race_guard/shared_state/trace_point.rb,
lib/race_guard/shared_state/access_event.rb,
lib/race_guard/shared_state/memo_scanner.rb,
lib/race_guard/index_integrity/schema_ast.rb,
lib/race_guard/interceptors/action_mailer.rb,
lib/race_guard/reporters/webhook_reporter.rb,
lib/race_guard/shared_state/memo_registry.rb,
lib/race_guard/distributed/memory_lock_store.rb,
lib/race_guard/index_integrity/model_scanner.rb,
lib/race_guard/index_integrity/schema_walker.rb,
lib/race_guard/shared_state/conflict_tracker.rb,
lib/race_guard/index_integrity/validation_ast.rb,
lib/race_guard/index_integrity/schema_analyzer.rb,
lib/race_guard/index_integrity/table_inference.rb,
lib/race_guard/db_lock_auditor/read_modify_write.rb,
lib/race_guard/index_integrity/comparison_engine.rb,
lib/race_guard/index_integrity/schema_index_send.rb,
lib/generators/race_guard/install/install_generator.rb,
lib/race_guard/index_integrity/schema_connection_indexes.rb

Overview

LockStore protocol uses claim / renew / release (not predicate names) for adapter symmetry. rubocop:disable Naming/PredicateMethod

Defined Under Namespace

Modules: ActiveRecord, CommitSafety, Context, DBLockAuditor, DetectorRuntime, Distributed, Generators, IndexIntegrity, Interceptors, MethodResolution, MethodWatch, Reporters, RuleEngine, SharedState Classes: Configuration, Event, ReportRaisedError, Rule

Constant Summary collapse

VERSION =
'0.2.0'
SEVERITY_LEVELS =
%i[info warn error raise].freeze
DISTRIBUTED_GUARD_FEATURE =

Epic 10 — enable with RaceGuard.configure { |c| c.enable(:distributed_guard) }.

:distributed_guard

Class Method Summary collapse

Class Method Details

.after_commit(&block) ⇒ Object

Raises:

  • (ArgumentError)


52
53
54
55
56
57
58
59
60
61
# File 'lib/race_guard.rb', line 52

def after_commit(&block)
  raise ArgumentError, 'RaceGuard.after_commit requires a block' unless block

  if context.current.in_transaction?
    context.defer_after_commit(&block)
  else
    run_after_commit_immediate(block)
  end
  self
end

.configurationObject Also known as: config



23
24
25
# File 'lib/race_guard.rb', line 23

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



29
30
31
32
33
# File 'lib/race_guard.rb', line 29

def configure
  yield configuration
  SharedState::MemoRegistry.sync_from_configuration!
  SharedState::TracePoint.sync_with_configuration!
end

.contextObject



40
41
42
# File 'lib/race_guard.rb', line 40

def context
  @context ||= Context::Facade.new
end

.define_rule(name) ⇒ Object



48
49
50
# File 'lib/race_guard.rb', line 48

def define_rule(name, &)
  RuleEngine.define_rule(name, &)
end

.distributed_once(name, ttl:, resource: nil, on_skip: nil, &block) ⇒ Object

Epic 10 — distributed execution guard (Redis-backed RaceGuard::Distributed::LockStore). Requires c.enable(:distributed_guard) and a configured distributed_lock_store or distributed_redis_client when active.



66
67
68
# File 'lib/race_guard.rb', line 66

def distributed_once(name, ttl:, resource: nil, on_skip: nil, &block)
  Distributed::Runner.run(name: name, ttl: ttl, resource: resource, on_skip: on_skip, &block)
end

.distributed_protect(name, ttl:, resource: nil, on_skip: nil, &block) ⇒ Object

Alias for distributed_once (same semantics).



71
72
73
# File 'lib/race_guard.rb', line 71

def distributed_protect(name, ttl:, resource: nil, on_skip: nil, &block)
  distributed_once(name, ttl: ttl, resource: resource, on_skip: on_skip, &block)
end

.protect(name, &block) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/race_guard/protection.rb', line 6

def self.protect(name, &block)
  raise ArgumentError, 'RaceGuard.protect requires a block' unless block

  sym = name.to_sym
  context.push_protected(sym)
  DetectorRuntime.enter(sym)
  yield
ensure
  safe_protect_exit(sym)
  context.pop_protected
end

.report(payload) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/race_guard.rb', line 75

def report(payload)
  cfg = configuration
  return nil unless cfg.active?

  event = Event.from_payload(payload)
  event = merge_protect_context(event)
  cfg.reporters.each do |reporter|
    reporter.report(event)
  rescue StandardError
    # isolate reporter failure
  end

  raise ReportRaisedError, event if event.severity == :raise

  nil
end

.reset_configuration!Object



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

def reset_configuration!
  SharedState::TracePoint.uninstall!
  @configuration = nil
end

.watch(klass, method_name, scope: :auto) ⇒ Object



44
45
46
# File 'lib/race_guard.rb', line 44

def watch(klass, method_name, scope: :auto)
  MethodWatch.watch(klass, method_name, scope: scope)
end