Class: PactBroker::DB::CleanTask
- Inherits:
-
Rake::TaskLib
- Object
- Rake::TaskLib
- PactBroker::DB::CleanTask
- Defined in:
- lib/pact_broker/tasks/clean_task.rb
Instance Attribute Summary collapse
-
#database_connection ⇒ Object
Returns the value of attribute database_connection.
-
#dry_run ⇒ Object
Returns the value of attribute dry_run.
-
#keep_version_selectors ⇒ Object
Returns the value of attribute keep_version_selectors.
-
#logger ⇒ Object
Returns the value of attribute logger.
-
#use_lock ⇒ Object
allow disabling of postgres lock if it is causing problems.
-
#version_deletion_limit ⇒ Object
Returns the value of attribute version_deletion_limit.
Instance Method Summary collapse
- #add_defaults_to_keep_selectors ⇒ Object
-
#initialize(&block) ⇒ CleanTask
constructor
A new instance of CleanTask.
- #output(string, payload = {}) ⇒ Object
- #perform_clean ⇒ Object
- #rake_task(&block) ⇒ Object
-
#with_lock ⇒ Object
Use a Postgres advisory lock to ensure that only one clean can run at a time.
Constructor Details
#initialize(&block) ⇒ CleanTask
Returns a new instance of CleanTask.
17 18 19 20 21 22 23 24 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 17 def initialize &block require "pact_broker/db/clean_incremental" @version_deletion_limit = 1000 @dry_run = false @use_lock = true @keep_version_selectors = PactBroker::DB::CleanIncremental::DEFAULT_KEEP_SELECTORS rake_task(&block) end |
Instance Attribute Details
#database_connection ⇒ Object
Returns the value of attribute database_connection.
10 11 12 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 10 def database_connection @database_connection end |
#dry_run ⇒ Object
Returns the value of attribute dry_run.
14 15 16 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 14 def dry_run @dry_run end |
#keep_version_selectors ⇒ Object
Returns the value of attribute keep_version_selectors.
11 12 13 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 11 def keep_version_selectors @keep_version_selectors end |
#logger ⇒ Object
Returns the value of attribute logger.
13 14 15 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 13 def logger @logger end |
#use_lock ⇒ Object
allow disabling of postgres lock if it is causing problems
15 16 17 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 15 def use_lock @use_lock end |
#version_deletion_limit ⇒ Object
Returns the value of attribute version_deletion_limit.
12 13 14 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 12 def version_deletion_limit @version_deletion_limit end |
Instance Method Details
#add_defaults_to_keep_selectors ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 111 def add_defaults_to_keep_selectors if keep_version_selectors.none?(&:currently_deployed?) selector = PactBroker::DB::Clean::Selector.new(deployed: true) output("Automatically adding #{selector.to_hash} to keep version selectors") keep_version_selectors << selector end if keep_version_selectors.none?(&:currently_supported?) selector = PactBroker::DB::Clean::Selector.new(released: true) output("Automatically adding #{ selector.to_hash } to keep version selectors") keep_version_selectors << selector end end |
#output(string, payload = {}) ⇒ Object
106 107 108 109 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 106 def output(string, payload = {}) prefix = dry_run ? "[DRY RUN] " : "" logger ? logger.info("#{prefix}#{string}", payload) : puts("#{prefix}#{string} #{payload.to_json}") end |
#perform_clean ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 48 def perform_clean require "pact_broker/db/clean_incremental" require "pact_broker/error" require "yaml" require "benchmark" raise PactBroker::Error.new("You must specify the version_deletion_limit") unless version_deletion_limit if keep_version_selectors.nil? || keep_version_selectors.empty? raise PactBroker::Error.new("You must specify which versions to keep") else add_defaults_to_keep_selectors output "Deleting oldest #{version_deletion_limit} versions, keeping versions that match the configured selectors", keep_version_selectors.collect(&:to_hash) end start_time = Time.now results = PactBroker::DB::CleanIncremental.call(database_connection, keep: keep_version_selectors, limit: version_deletion_limit, logger: logger, dry_run: dry_run ) end_time = Time.now elapsed_seconds = (end_time - start_time).to_i output "Results (#{elapsed_seconds} seconds)", results end |
#rake_task(&block) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 33 def rake_task &block namespace :pact_broker do namespace :db do desc "Clean unnecessary pacts and verifications from database" task :clean do | _t, _args | instance_eval(&block) with_lock do perform_clean end end end end end |
#with_lock ⇒ Object
Use a Postgres advisory lock to ensure that only one clean can run at a time. This allows a cron schedule to be used on the Pact Broker Docker image when deployed on a multi-instance architecture, without all the instances stepping on each other’s toes.
Any tasks that attempt to run while a clean job is running will skip the clean and exit with a message and a success code.
To test that the lock works, run:
script/docker/db-start.sh
script/docker/db-migrate.sh
for i in {0..3}; do PACT_BROKER_TEST_DATABASE_URL=postgres://postgres:postgres@localhost/postgres bundle exec rake pact_broker:db:clean &; done;
There will be 3 messages saying “Clean was not performed” and output from one thread showing the clean is being done.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/pact_broker/tasks/clean_task.rb', line 88 def with_lock if use_lock require "pact_broker/db/advisory_lock" lock = PactBroker::DB::AdvisoryLock.new(database_connection, :clean, :pg_try_advisory_lock) results = lock.with_lock do yield end if !lock.lock_obtained? output("Clean was not performed as a clean is already in progress. Exiting.") end results else yield end end |