1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
module Flipper
module Adapters
class Sync
# Internal: Wraps a Synchronizer instance and only invokes it every
# N milliseconds.
class IntervalSynchronizer
# Private: Number of milliseconds between syncs (default: 10 seconds).
DEFAULT_INTERVAL_MS = 10_000
# Private
def self.now_ms
Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
end
# Public: The number of milliseconds between invocations of the
# wrapped synchronizer.
attr_reader :interval
# Public: Initializes a new interval synchronizer.
#
# synchronizer - The Synchronizer to call when the interval has passed.
# interval - The Integer number of milliseconds between invocations of
# the wrapped synchronizer.
def initialize(synchronizer, interval: nil)
@synchronizer = synchronizer
@interval = interval || DEFAULT_INTERVAL_MS
# TODO: add jitter to this so all processes booting at the same time
# don't phone home at the same time.
@last_sync_at = 0
end
def call
return unless time_to_sync?
@last_sync_at = now_ms
@synchronizer.call
nil
end
private
def time_to_sync?
(now_ms - @last_sync_at) >= @interval
end
def now_ms
self.class.now_ms
end
end
end
end
end
|