Class: Hatchet::Reaper
- Inherits:
-
Object
- Object
- Hatchet::Reaper
- Defined in:
- lib/hatchet/reaper.rb
Overview
Hatchet apps are useful after the tests run for debugging purposes the reaper is designed to allow the most recent apps to stay alive while keeping the total number of apps under the global Heroku limit. Any time you’re worried about hitting the limit call @reaper.cycle
Constant Summary collapse
- HEROKU_APP_LIMIT =
the number of apps heroku allows you to keep
Integer(ENV["HEROKU_APP_LIMIT"] || 100)
- HATCHET_APP_LIMT =
the number of apps hatchet keeps around
Integer(ENV["HATCHET_APP_LIMIT"] || 20)
- DEFAULT_REGEX =
/^#{Regexp.escape(Hatchet::APP_PREFIX)}[a-f0-9]+/
Instance Attribute Summary collapse
-
#apps ⇒ Object
Returns the value of attribute apps.
Instance Method Summary collapse
- #cycle ⇒ Object
- #destroy_all ⇒ Object
- #destroy_by_id(name:, id:, details: "") ⇒ Object
- #destroy_oldest ⇒ Object
-
#get_apps ⇒ Object
Ascending order, oldest is last.
-
#initialize(api_rate_limit:, regex: DEFAULT_REGEX) ⇒ Reaper
constructor
A new instance of Reaper.
Constructor Details
#initialize(api_rate_limit:, regex: DEFAULT_REGEX) ⇒ Reaper
Returns a new instance of Reaper.
15 16 17 18 |
# File 'lib/hatchet/reaper.rb', line 15 def initialize(api_rate_limit: , regex: DEFAULT_REGEX) @api_rate_limit = api_rate_limit @regex = regex end |
Instance Attribute Details
#apps ⇒ Object
Returns the value of attribute apps.
13 14 15 |
# File 'lib/hatchet/reaper.rb', line 13 def apps @apps end |
Instance Method Details
#cycle ⇒ Object
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 54 55 56 57 58 59 60 61 62 |
# File 'lib/hatchet/reaper.rb', line 27 def cycle # we don't want multiple Hatchet processes (e.g. when using rspec-parallel) to delete apps at the same time # this could otherwise result in race conditions in API causing errors other than 404s, making tests fail mutex = File.open("#{Dir.tmpdir()}/hatchet_reaper_mutex", File::CREAT) mutex.flock(File::LOCK_EX) # update list of apps once get_apps return unless over_limit? while over_limit? if @hatchet_apps.count > 1 # remove our own apps until we are below limit destroy_oldest else puts "Warning: Reached Heroku app limit of #{HEROKU_APP_LIMIT}." break end end # If the app is already deleted an exception # will be raised, if the app cannot be found # assume it is already deleted and try again rescue Excon::Error::NotFound => e body = e.response.body if body =~ /Couldn\'t find that app./ puts "#{@message}, but looks like it was already deleted" mutex.close # ensure only gets called on block exit and not on `retry` retry end raise e ensure # don't forget to close the mutex; this also releases our lock mutex.close end |
#destroy_all ⇒ Object
69 70 71 72 73 74 |
# File 'lib/hatchet/reaper.rb', line 69 def destroy_all get_apps @hatchet_apps.each do |app| destroy_by_id(name: app["name"], id: app["id"]) end end |
#destroy_by_id(name:, id:, details: "") ⇒ Object
76 77 78 79 80 |
# File 'lib/hatchet/reaper.rb', line 76 def destroy_by_id(name:, id:, details: "") @message = "Destroying #{name.inspect}: #{id}. #{details}" puts @message @api_rate_limit.call.app.delete(id) end |
#destroy_oldest ⇒ Object
64 65 66 67 |
# File 'lib/hatchet/reaper.rb', line 64 def destroy_oldest oldest = @hatchet_apps.pop destroy_by_id(name: oldest["name"], id: oldest["id"], details: "Hatchet app limit: #{HATCHET_APP_LIMT}") end |
#get_apps ⇒ Object
Ascending order, oldest is last
21 22 23 24 25 |
# File 'lib/hatchet/reaper.rb', line 21 def get_apps apps = @api_rate_limit.call.app.list.sort_by { |app| DateTime.parse(app["created_at"]) }.reverse @app_count = apps.count @hatchet_apps = apps.select {|app| app["name"].match(@regex) } end |