Module: GSKCache
- Defined in:
- lib/gsk_cache.rb
Constant Summary collapse
- SIGNING_KEY_URL =
Keys used for signing in production
'https://payments.developers.google.com/paymentmethodtoken/keys.json'.freeze
- TEST_SIGNING_KEY_URL =
Keys used for signing in a testing environment
'https://payments.developers.google.com/paymentmethodtoken/test/keys.json'.freeze
- MAX_CACHE_TIMEOUT =
One month
31 * 24 * 3600
- MIN_CACHE_TIMEOUT =
10 minutes
600- BOOT_WAIT_TIME_MAX =
8- HEADER_KEY =
'Cache-Control'.freeze
- READ_TIMEOUT =
10- CONNECT_TIMEOUT =
10- UPDATER_BLOCK =
proc do loop do begin timeout = 0 conn = Excon.new(@@source, connect_timeout: @@connect_timeout, read_timeout: @@read_timeout) resp = conn.get raise 'Unable to update keys: ' + resp.data[:status_line] unless resp.status == 200 if resp.headers.key?(HEADER_KEY) && resp.headers[HEADER_KEY].is_a?(String) cache_control = resp.headers[HEADER_KEY].split(/,\s*/) h = cache_control.map { |x| /\Amax-age=(?<timeout>\d+)\z/ =~ x; timeout }.compact timeout = h.first.to_i if h.length == 1 else log(:warning, "Missing/malformed #{HEADER_KEY} header") end if timeout.nil? || !timeout.positive? log(:warning, 'Cache timeout was not parsed, falling back to 1 day') timeout = 86400 end # Fallback to longer cache if less than 10 minutes if timeout < MIN_CACHE_TIMEOUT log(:warning, "Cache timeout less than 10 minutes (#{timeout}s), defaulting to #{MIN_CACHE_TIMEOUT / 60} minutes") timeout = MIN_CACHE_TIMEOUT end # Fallback to shorter cache if longer than 30 days if timeout > MAX_CACHE_TIMEOUT log(:warning, "Cache timeout more than a month (#{timeout}s), defaulting to #{MAX_CACHE_TIMEOUT / (24 * 3600)} days") timeout = MAX_CACHE_TIMEOUT end Thread.current.thread_variable_set('keys', resp.body) # Supposedly recommended by Tink library sleep_time = timeout / 2 log(:info, "Updated Google signing keys. Sleeping for #{seconds_to_time(sleep_time)}") sleep sleep_time rescue Interrupt => e # When interrupted log(:fatal, 'Quitting: ' + e.) return rescue => e log(:error, "Exception updating Google signing keys: '#{e.}' at #{e.backtrace}") # Don't retry excessively. sleep 1 end end end
- @@key_updater_semaphore =
Mutex.new
- @@key_updater_thread =
nil
Class Method Summary collapse
- .set_timeout(read_timeout: nil, connect_timeout: nil) ⇒ Object
- .signing_keys ⇒ Object
-
.start(logger: nil, source: nil, waittime: BOOT_WAIT_TIME_MAX) ⇒ Object
Start a thread that keeps the Google signing keys updated.
-
.terminate ⇒ Object
Required for specs.
Class Method Details
.set_timeout(read_timeout: nil, connect_timeout: nil) ⇒ Object
115 116 117 118 |
# File 'lib/gsk_cache.rb', line 115 def self.set_timeout(read_timeout: nil, connect_timeout: nil) @@read_timeout = read_timeout if read_timeout @@connect_timeout = connect_timeout if connect_timeout end |
.signing_keys ⇒ Object
120 121 122 123 124 |
# File 'lib/gsk_cache.rb', line 120 def self.signing_keys start if @@key_updater_thread.nil? @@key_updater_thread.thread_variable_get('keys') end |
.start(logger: nil, source: nil, waittime: BOOT_WAIT_TIME_MAX) ⇒ Object
Start a thread that keeps the Google signing keys updated.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/gsk_cache.rb', line 84 def self.start(logger: nil, source: nil, waittime: BOOT_WAIT_TIME_MAX) @@key_updater_semaphore.synchronize do # Another thread might have been waiting for on the mutex break unless @@key_updater_thread.nil? @@logger = logger @@source = if source source elsif ENV['ENVIRONMENT'] == 'production' SIGNING_KEY_URL else TEST_SIGNING_KEY_URL end @@read_timeout = READ_TIMEOUT @@connect_timeout = CONNECT_TIMEOUT new_thread = Thread.new(&UPDATER_BLOCK) start_time = Time.now.to_i while new_thread.thread_variable_get('keys').nil? && Time.now.to_i - start_time < waittime sleep 0.2 end # Body has now been set. # Let other clients through. @@key_updater_thread = new_thread nil end end |
.terminate ⇒ Object
Required for specs
127 128 129 130 |
# File 'lib/gsk_cache.rb', line 127 def self.terminate @@key_updater_thread&.terminate @@key_updater_thread = nil end |