class Unleash::ToggleFetcher
Attributes
etag[RW]
retry_count[RW]
toggle_cache[RW]
toggle_lock[RW]
toggle_resource[RW]
Public Class Methods
new()
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 9 def initialize self.etag = nil self.toggle_cache = nil self.toggle_lock = Mutex.new self.toggle_resource = ConditionVariable.new self.retry_count = 0 # start by fetching synchronously, and failing back to reading the backup file. begin fetch rescue StandardError => e Unleash.logger.warn "ToggleFetcher was unable to fetch from the network, attempting to read from backup file." Unleash.logger.debug "Exception Caught: #{e}" read! end # once initialized, somewhere else you will want to start a loop with fetch() end
Public Instance Methods
fetch()
click to toggle source
rename to refresh_from_server! ??
# File lib/unleash/toggle_fetcher.rb, line 37 def fetch Unleash.logger.debug "fetch()" response = Unleash::Util::Http.get(Unleash.configuration.fetch_toggles_url, etag) if response.code == '304' Unleash.logger.debug "No changes according to the unleash server, nothing to do." return elsif response.code != '200' raise IOError, "Unleash server returned a non 200/304 HTTP result." end self.etag = response['ETag'] response_hash = JSON.parse(response.body) if response_hash['version'] >= 1 features = response_hash['features'] else raise NotImplemented, "Version of features provided by unleash server" \ " is unsupported by this client." end # always synchronize with the local cache when fetching: synchronize_with_local_cache!(features) update_running_client! save! end
save!()
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 65 def save! Unleash.logger.debug "Will save toggles to disk now" begin backup_file = Unleash.configuration.backup_file backup_file_tmp = "#{backup_file}.tmp" self.toggle_lock.synchronize do file = File.open(backup_file_tmp, "w") file.write(self.toggle_cache.to_json) file.close File.rename(backup_file_tmp, backup_file) end rescue StandardError => e # This is not really the end of the world. Swallowing the exception. Unleash.logger.error "Unable to save backup file. Exception thrown #{e.class}:'#{e}'" Unleash.logger.error "stacktrace: #{e.backtrace}" ensure file&.close if defined?(file) self.toggle_lock.unlock if self.toggle_lock.locked? end end
toggles()
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 28 def toggles self.toggle_lock.synchronize do # wait for resource, only if it is null self.toggle_resource.wait(self.toggle_lock) if self.toggle_cache.nil? return self.toggle_cache end end
Private Instance Methods
read!()
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 107 def read! Unleash.logger.debug "read!()" return nil unless File.exist?(Unleash.configuration.backup_file) begin file = File.new(Unleash.configuration.backup_file, "r") file_content = file.read backup_as_hash = JSON.parse(file_content) synchronize_with_local_cache!(backup_as_hash) update_running_client! rescue IOError => e Unleash.logger.error "Unable to read the backup_file: #{e}" rescue JSON::ParserError => e Unleash.logger.error "Unable to parse JSON from existing backup_file: #{e}" rescue StandardError => e Unleash.logger.error "Unable to extract valid data from backup_file. Exception thrown: #{e}" ensure file&.close end end
synchronize_with_local_cache!(features)
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 89 def synchronize_with_local_cache!(features) if self.toggle_cache != features self.toggle_lock.synchronize do self.toggle_cache = features end # notify all threads waiting for this resource to no longer wait self.toggle_resource.broadcast end end
update_running_client!()
click to toggle source
# File lib/unleash/toggle_fetcher.rb, line 100 def update_running_client! if Unleash.toggles != self.toggles Unleash.logger.info "Updating toggles to main client, there has been a change in the server." Unleash.toggles = self.toggles end end