|
| 1 | +# Example showing poll interval being dynamically adjusted via poll-interval header |
| 2 | +# |
| 3 | +# Usage: |
| 4 | +# 1. Terminal 1: bundle exec ruby examples/cloud/poll_interval/server.rb |
| 5 | +# 2. Terminal 2: bundle exec ruby examples/cloud/poll_interval/client.rb |
| 6 | + |
| 7 | +require 'bundler/setup' |
| 8 | +require 'flipper' |
| 9 | +require 'flipper/adapters/http' |
| 10 | +require 'flipper/poller' |
| 11 | +require 'logger' |
| 12 | + |
| 13 | +# Setup logging to show what's happening |
| 14 | +logger = Logger.new(STDOUT) |
| 15 | +logger.level = Logger::INFO |
| 16 | +logger.formatter = proc do |severity, datetime, progname, msg| |
| 17 | + "[#{datetime.strftime('%H:%M:%S')}] #{severity}: #{msg}\n" |
| 18 | +end |
| 19 | + |
| 20 | +# Create HTTP adapter pointing to localhost:3000 |
| 21 | +http_adapter = Flipper::Adapters::Http.new(url: 'http://localhost:3000/flipper') |
| 22 | + |
| 23 | +# Create instrumenter to log poller events |
| 24 | +instrumenter = Module.new do |
| 25 | + def self.instrument(name, payload = {}) |
| 26 | + case payload[:operation] |
| 27 | + when :poll |
| 28 | + logger.info "Polling remote adapter..." |
| 29 | + when :shutdown_requested |
| 30 | + logger.warn "Shutdown requested by server via poll-shutdown header" |
| 31 | + when :stop |
| 32 | + logger.warn "Poller stopped" |
| 33 | + when :thread_start |
| 34 | + logger.info "Poller thread started" |
| 35 | + end |
| 36 | + |
| 37 | + result = yield if block_given? |
| 38 | + |
| 39 | + if payload[:operation] == :poll && result |
| 40 | + logger.info "Poll completed successfully" |
| 41 | + end |
| 42 | + |
| 43 | + result |
| 44 | + end |
| 45 | + |
| 46 | + def self.logger=(l) |
| 47 | + @logger = l |
| 48 | + end |
| 49 | + |
| 50 | + def self.logger |
| 51 | + @logger |
| 52 | + end |
| 53 | +end |
| 54 | +instrumenter.logger = logger |
| 55 | + |
| 56 | +# Create poller with custom instrumenter and short initial interval |
| 57 | +poller = Flipper::Poller.new( |
| 58 | + remote_adapter: http_adapter, |
| 59 | + interval: 5, # Start with 5 second interval (will be enforced to 10 minimum) |
| 60 | + instrumenter: instrumenter, |
| 61 | + start_automatically: false, |
| 62 | + shutdown_automatically: false |
| 63 | +) |
| 64 | + |
| 65 | +logger.info "Starting poller with interval: #{poller.interval} seconds" |
| 66 | +logger.info "Minimum allowed interval: #{Flipper::Poller::MINIMUM_POLL_INTERVAL} seconds" |
| 67 | +logger.info "" |
| 68 | +logger.info "Server can control polling via response headers:" |
| 69 | +logger.info " - poll-interval: <seconds> (adjust poll frequency)" |
| 70 | +logger.info " - poll-shutdown: true (stop polling)" |
| 71 | +logger.info "" |
| 72 | + |
| 73 | +# Track interval changes |
| 74 | +last_interval = poller.interval |
| 75 | + |
| 76 | +# Start the poller |
| 77 | +poller.start |
| 78 | + |
| 79 | +# Monitor for interval changes and log them |
| 80 | +logger.info "Monitoring poller... (Ctrl+C to exit)" |
| 81 | +logger.info "" |
| 82 | + |
| 83 | +begin |
| 84 | + loop do |
| 85 | + sleep 2 |
| 86 | + |
| 87 | + current_interval = poller.interval |
| 88 | + |
| 89 | + # Highlight when it changes |
| 90 | + if current_interval != last_interval |
| 91 | + logger.warn "⚠️ INTERVAL CHANGED: #{last_interval}s → #{current_interval}s" |
| 92 | + last_interval = current_interval |
| 93 | + end |
| 94 | + |
| 95 | + # Check if poller thread is still alive |
| 96 | + unless poller.thread&.alive? |
| 97 | + logger.warn "Poller thread is no longer running" |
| 98 | + break |
| 99 | + end |
| 100 | + end |
| 101 | +rescue Interrupt |
| 102 | + logger.info "" |
| 103 | + logger.info "Interrupted by user" |
| 104 | +ensure |
| 105 | + logger.info "Stopping poller..." |
| 106 | + poller.stop |
| 107 | + logger.info "Final interval: #{poller.interval} seconds" |
| 108 | +end |
0 commit comments