Module: RaceGuard::RuleEngine
- Defined in:
- lib/race_guard/rule_engine.rb
Overview
Registry + dispatch for user-defined rules (see define_rule).
Constant Summary collapse
- REGISTRY =
rubocop:disable Style/MutableConstant – process-wide mutable registry
{}
- REGISTRY_MUTEX =
Mutex.new
Class Method Summary collapse
- .define_rule(name) {|builder| ... } ⇒ Object
- .dispatch(event, metadata = {}) ⇒ Object
- .evaluate(name, metadata: {}) ⇒ Object
- .evaluate_and_report(rule_name, rule, meta) ⇒ Object
- .normalize_metadata(metadata) ⇒ Object
-
.reset_registry! ⇒ Object
Test helper: clears the rule registry (does not disable rules in config).
- .rule_defined?(name) ⇒ Boolean
- .run_rule_hooks(rule, meta) ⇒ Object
Class Method Details
.define_rule(name) {|builder| ... } ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/race_guard/rule_engine.rb', line 11 def self.define_rule(name, &) raise ArgumentError, 'RaceGuard.define_rule requires a block' unless block_given? sym = name.to_sym builder = Rule::Builder.new(sym) yield builder rule = builder.build REGISTRY_MUTEX.synchronize do raise ArgumentError, "rule #{sym.inspect} is already defined" if REGISTRY.key?(sym) REGISTRY[sym] = rule end RaceGuard end |
.dispatch(event, metadata = {}) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/race_guard/rule_engine.rb', line 27 def self.dispatch(event, = {}) sym = event.to_sym = ().merge(event: sym) rules_snapshot = REGISTRY_MUTEX.synchronize { REGISTRY.dup } cfg = RaceGuard.configuration rules_snapshot.each do |rule_name, rule| next unless cfg.enabled_rule?(rule_name) run_rule_hooks(rule, ) next unless rule.run_on?(sym) evaluate_and_report(rule_name, rule, ) end nil end |
.evaluate(name, metadata: {}) ⇒ Object
44 45 46 47 48 49 50 51 52 |
# File 'lib/race_guard/rule_engine.rb', line 44 def self.evaluate(name, metadata: {}) sym = name.to_sym rule = REGISTRY_MUTEX.synchronize { REGISTRY[sym] } return nil unless rule return nil unless RaceGuard.configuration.enabled_rule?(sym) = ().merge(event: :evaluate) evaluate_and_report(sym, rule, ) end |
.evaluate_and_report(rule_name, rule, meta) ⇒ Object
83 84 85 86 87 88 89 90 91 92 |
# File 'lib/race_guard/rule_engine.rb', line 83 def self.evaluate_and_report(rule_name, rule, ) ctx = RaceGuard.context.current return unless rule.detect_proc.call(ctx, ) msg = rule..call(ctx, ).to_s sev = rule.severity_override || RaceGuard.configuration.severity_for(rule_name) RaceGuard.report(detector: rule_name.to_s, message: msg, severity: sev) rescue StandardError nil end |
.normalize_metadata(metadata) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/race_guard/rule_engine.rb', line 65 def self.() h = || {} return h.transform_keys(&:to_sym) if h.respond_to?(:transform_keys) h.each_with_object({}) do |(k, v), o| sym = k.respond_to?(:to_sym) ? k.to_sym : k.to_s.to_sym o[sym] = v end end |
.reset_registry! ⇒ Object
Test helper: clears the rule registry (does not disable rules in config).
60 61 62 63 |
# File 'lib/race_guard/rule_engine.rb', line 60 def self.reset_registry! REGISTRY_MUTEX.synchronize { REGISTRY.clear } nil end |
.rule_defined?(name) ⇒ Boolean
54 55 56 57 |
# File 'lib/race_guard/rule_engine.rb', line 54 def self.rule_defined?(name) sym = name.to_sym REGISTRY_MUTEX.synchronize { REGISTRY.key?(sym) } end |