Class: ScoutApm::Layaway
- Inherits:
-
Object
- Object
- ScoutApm::Layaway
- Defined in:
- lib/scout_apm/layaway.rb
Constant Summary collapse
- STALE_AGE =
How long to let a stale file sit before deleting it. Letting it sit a bit may be useful for debugging
10 * 60
- MAX_FILES_LIMIT =
Failsafe to prevent writing layaway files if for some reason they are not being cleaned up
5000
- TIME_FORMAT =
A strftime format string for how we render timestamps in filenames. Must be sortable as an integer
"%Y%m%d%H%M"
Instance Attribute Summary collapse
-
#config ⇒ Object
Returns the value of attribute config.
-
#environment ⇒ Object
readonly
Returns the value of attribute environment.
Instance Method Summary collapse
- #delete_files_for(timestamp) ⇒ Object
- #delete_stale_files(older_than) ⇒ Object
-
#directory ⇒ Object
Returns a Pathname object with the fully qualified directory where the layaway files can be placed.
-
#initialize(config, environment) ⇒ Layaway
constructor
A new instance of Layaway.
-
#with_claim(timestamp) ⇒ Object
Claims a given timestamp (getting a lock on a particular filename), then yields ReportingPeriods collected up from all the files.
- #write_reporting_period(reporting_period, files_limit = MAX_FILES_LIMIT) ⇒ Object
Constructor Details
#initialize(config, environment) ⇒ Layaway
Returns a new instance of Layaway.
24 25 26 27 |
# File 'lib/scout_apm/layaway.rb', line 24 def initialize(config, environment) @config = config @environment = environment end |
Instance Attribute Details
#config ⇒ Object
Returns the value of attribute config.
21 22 23 |
# File 'lib/scout_apm/layaway.rb', line 21 def config @config end |
#environment ⇒ Object (readonly)
Returns the value of attribute environment.
22 23 24 |
# File 'lib/scout_apm/layaway.rb', line 22 def environment @environment end |
Instance Method Details
#delete_files_for(timestamp) ⇒ Object
112 113 114 115 116 117 |
# File 'lib/scout_apm/layaway.rb', line 112 def delete_files_for() all_files_for().each { |layaway| ScoutApm::Agent.instance.logger.debug("Deleting layaway file: #{layaway}") File.unlink(layaway) } end |
#delete_stale_files(older_than) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/scout_apm/layaway.rb', line 119 def delete_stale_files(older_than) all_files_for(:all). map { |filename| (filename) }. compact. uniq. select { || .to_i < older_than.strftime(TIME_FORMAT).to_i }. tap { || ScoutApm::Agent.instance.logger.debug("Deleting stale layaway files with timestamps: #{.inspect}") }. map { || delete_files_for() } rescue => e ScoutApm::Agent.instance.logger.debug("Problem deleting stale files: #{e.}, #{e.backtrace.inspect}") end |
#directory ⇒ Object
Returns a Pathname object with the fully qualified directory where the layaway files can be placed. That directory must be writable by this process.
Don’t set this in initializer, since it relies on agent instance existing to figure out the value.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/scout_apm/layaway.rb', line 34 def directory return @directory if @directory data_file = config.value("data_file") data_file = File.dirname(data_file) if data_file && !File.directory?(data_file) candidates = [ data_file, "#{environment.root}/tmp", "/tmp" ].compact found = candidates.detect { |dir| File.writable?(dir) } ScoutApm::Agent.instance.logger.debug("Storing Layaway Files in #{found}") @directory = Pathname.new(found) end |
#with_claim(timestamp) ⇒ Object
Claims a given timestamp (getting a lock on a particular filename), then yields ReportingPeriods collected up from all the files. If the yield returns truthy, delete the layaway files that made it up.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 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 |
# File 'lib/scout_apm/layaway.rb', line 64 def with_claim() coordinator_file = glob_pattern(, :coordinator) begin # This file gets deleted only by a process that successfully created and obtained the exclusive lock f = File.open(coordinator_file, File::RDWR | File::CREAT | File::EXCL | File::NONBLOCK) rescue Errno::EEXIST false end begin if f begin ScoutApm::Agent.instance.logger.debug("Obtained Reporting Lock") log_layaway_file_information files = all_files_for().reject{|l| l.to_s == coordinator_file.to_s } rps = files.map{ |layaway| LayawayFile.new(layaway).load }.compact if rps.any? yield rps ScoutApm::Agent.instance.logger.debug("Deleting the now-reported layaway files for #{.to_s}") delete_files_for() # also removes the coodinator_file ScoutApm::Agent.instance.logger.debug("Checking for any Stale layaway files") delete_stale_files(.to_time - STALE_AGE) else File.unlink(coordinator_file) ScoutApm::Agent.instance.logger.debug("No layaway files to report") end true rescue Exception => e ScoutApm::Agent.instance.logger.debug("Caught an exception in with_claim, with the coordination file locked: #{e.}, #{e.backtrace.inspect}") raise ensure # Unlock the file when done! f.flock(File::LOCK_UN | File::LOCK_NB) f.close end else # Didn't obtain lock, another process is reporting. Return false from this function, but otherwise no work false end end end |
#write_reporting_period(reporting_period, files_limit = MAX_FILES_LIMIT) ⇒ Object
51 52 53 54 55 56 57 58 59 |
# File 'lib/scout_apm/layaway.rb', line 51 def write_reporting_period(reporting_period, files_limit = MAX_FILES_LIMIT) if at_layaway_file_limit?(files_limit) ScoutApm::Agent.instance.logger.error("Hit layaway file limit. Not writing to layaway file") return false end filename = file_for(reporting_period.) layaway_file = LayawayFile.new(filename) layaway_file.write(reporting_period) end |