Class: Flipper::Poller

Inherits:
Object
  • Object
show all
Defined in:
lib/flipper/poller.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Poller

Returns a new instance of Poller.



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/flipper/poller.rb', line 23

def initialize(options = {})
  @thread = nil
  @pid = Process.pid
  @mutex = Mutex.new
  @instrumenter = options.fetch(:instrumenter, Instrumenters::Noop)
  @remote_adapter = options.fetch(:remote_adapter)
  @interval = options.fetch(:interval, 10).to_f
  @last_synced_at = Concurrent::AtomicFixnum.new(0)
  @adapter = Adapters::Memory.new(nil, threadsafe: true)

  if @interval < 1
    warn "Flipper::Cloud poll interval must be greater than or equal to 1 but was #{@interval}. Setting @interval to 1."
    @interval = 1
  end

  @start_automatically = options.fetch(:start_automatically, true)

  if options.fetch(:shutdown_automatically, true)
    at_exit { stop }
  end
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def adapter
  @adapter
end

#intervalObject (readonly)

Returns the value of attribute interval.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def interval
  @interval
end

#last_synced_atObject (readonly)

Returns the value of attribute last_synced_at.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def last_synced_at
  @last_synced_at
end

#mutexObject (readonly)

Returns the value of attribute mutex.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def mutex
  @mutex
end

#pidObject (readonly)

Returns the value of attribute pid.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def pid
  @pid
end

#threadObject (readonly)

Returns the value of attribute thread.



8
9
10
# File 'lib/flipper/poller.rb', line 8

def thread
  @thread
end

Class Method Details

.get(key, options = {}) ⇒ Object



15
16
17
# File 'lib/flipper/poller.rb', line 15

def self.get(key, options = {})
  instances.compute_if_absent(key) { new(options) }
end

.resetObject



19
20
21
# File 'lib/flipper/poller.rb', line 19

def self.reset
  instances.each {|_,poller| poller.stop }.clear
end

Instance Method Details

#runObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/flipper/poller.rb', line 57

def run
  loop do
    sleep jitter
    start = Concurrent.monotonic_time
    begin
      sync
    rescue => exception
      # you can instrument these using poller.flipper
    end

    sleep_interval = interval - (Concurrent.monotonic_time - start)
    sleep sleep_interval if sleep_interval.positive?
  end
end

#startObject



45
46
47
48
# File 'lib/flipper/poller.rb', line 45

def start
  reset if forked?
  ensure_worker_running
end

#stopObject



50
51
52
53
54
55
# File 'lib/flipper/poller.rb', line 50

def stop
  @instrumenter.instrument("poller.#{InstrumentationNamespace}", {
    operation: :stop,
  })
  @thread&.kill
end

#syncObject



72
73
74
75
76
77
# File 'lib/flipper/poller.rb', line 72

def sync
  @instrumenter.instrument("poller.#{InstrumentationNamespace}", operation: :poll) do
    @adapter.import @remote_adapter
    @last_synced_at.update { |time| Concurrent.monotonic_time }
  end
end