Class: Flare::RuleManager

Inherits:
Object
  • Object
show all
Defined in:
lib/flare/rule_manager.rb

Overview

The SDK’s only poll. Every interval seconds (default 30) it does a GET /api/rules; the 200 response carries the active TraceRules (with server-computed sample_rate) plus a bag of presigned R2 PUT URLs. We hand the rules to Sampler#update_rules and the URLs to UploadUrlPool#replace, and sweep the Marker so stuck rack-span entries don’t linger.

ETag-guarded: subsequent polls send If-None-Match. A 304 still gets us a Marker.sweep but doesn’t touch sampler or pool. 401/403 stops the poller (misconfigured token shouldn’t beat down the server). 5xx and exceptions are logged + counted; the timer just tries again on the next tick.

Fork-safe: after_fork clears the pool and restarts the timer in the child process so each child polls independently.

Constant Summary collapse

DEFAULT_INTERVAL =
30

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sampler:, marker:, pool:, base_url:, api_key:, project:, environment:, interval: DEFAULT_INTERVAL, transport: nil, logger: nil) ⇒ RuleManager

Returns a new instance of RuleManager.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/flare/rule_manager.rb', line 31

def initialize(sampler:, marker:, pool:, base_url:, api_key:, project:, environment:,
               interval: DEFAULT_INTERVAL, transport: nil, logger: nil)
  @sampler     = sampler
  @marker      = marker
  @pool        = pool
  @rules_url   = "#{base_url.to_s.chomp('/')}/api/rules"
  @api_key     = api_key
  @project     = project
  @environment = environment
  @interval    = interval
  @transport   = transport || HttpTransport.new
  @logger      = logger || Logger.new($stderr, level: Logger::WARN)

  @etag = nil
  @poll_count          = Concurrent::AtomicFixnum.new(0)
  @last_error_count    = Concurrent::AtomicFixnum.new(0)
  @stopped_due_to_auth = false
  @pid                 = $$
end

Instance Attribute Details

#etagObject (readonly)

Returns the value of attribute etag.



29
30
31
# File 'lib/flare/rule_manager.rb', line 29

def etag
  @etag
end

#last_error_countObject (readonly)

Returns the value of attribute last_error_count.



29
30
31
# File 'lib/flare/rule_manager.rb', line 29

def last_error_count
  @last_error_count
end

#poll_countObject (readonly)

Returns the value of attribute poll_count.



29
30
31
# File 'lib/flare/rule_manager.rb', line 29

def poll_count
  @poll_count
end

#stopped_due_to_authObject (readonly)

Returns the value of attribute stopped_due_to_auth.



29
30
31
# File 'lib/flare/rule_manager.rb', line 29

def stopped_due_to_auth
  @stopped_due_to_auth
end

Instance Method Details

#after_forkObject



76
77
78
79
80
81
# File 'lib/flare/rule_manager.rb', line 76

def after_fork
  @pid = $$
  @pool.after_fork
  stop
  start
end

#poll_nowObject

Public so callers can force a poll (tests + integration tests).



84
85
86
# File 'lib/flare/rule_manager.rb', line 84

def poll_now
  poll_safely
end

#running?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/flare/rule_manager.rb', line 72

def running?
  @timer ? @timer.running? : false
end

#startObject



51
52
53
54
55
56
57
58
59
60
# File 'lib/flare/rule_manager.rb', line 51

def start
  return self if @timer || @stopped_due_to_auth

  @timer = Concurrent::TimerTask.execute(
    execution_interval: @interval,
    run_now:            true,
    name:               "flare-rule-manager-timer"
  ) { poll_safely }
  self
end

#stopObject



62
63
64
65
66
67
68
69
70
# File 'lib/flare/rule_manager.rb', line 62

def stop
  if @timer
    @timer.shutdown
    @timer.wait_for_termination(1)
    @timer.kill unless @timer.shutdown?
    @timer = nil
  end
  self
end