Class: Harbor::DeployLock
- Inherits:
-
Object
- Object
- Harbor::DeployLock
- Defined in:
- lib/harbor/deploy_lock.rb
Instance Method Summary collapse
- #acquire!(project:, destination: nil, initiator: "cli") ⇒ Object
-
#initialize(lock_dir: nil, timeout: nil) ⇒ DeployLock
constructor
A new instance of DeployLock.
- #lock_info(project, destination = nil) ⇒ Object
- #locked?(project, destination = nil) ⇒ Boolean
- #refresh(project:, destination: nil) ⇒ Object
- #release(project:, destination: nil) ⇒ Object
Constructor Details
#initialize(lock_dir: nil, timeout: nil) ⇒ DeployLock
Returns a new instance of DeployLock.
9 10 11 12 13 |
# File 'lib/harbor/deploy_lock.rb', line 9 def initialize(lock_dir: nil, timeout: nil) @lock_dir = lock_dir || DEFAULT_LOCK_DIR @timeout = timeout || 1800 # 30 minutes default FileUtils.mkdir_p(@lock_dir) end |
Instance Method Details
#acquire!(project:, destination: nil, initiator: "cli") ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/harbor/deploy_lock.rb', line 15 def acquire!(project:, destination: nil, initiator: "cli") lock_file = lock_path(project, destination) if locked?(project, destination) info = lock_info(project, destination) raise LockConflict, "Deploy lock held for #{project}" \ "#{destination ? ":#{destination}" : ""} by #{info['initiator']} " \ "since #{info['timestamp']} (PID: #{info['pid']}). " \ "Lock expires in #{remaining_seconds(info)}s." end data = { pid: Process.pid, timestamp: Time.now.utc.iso8601, initiator: initiator, project: project, destination: destination } File.write(lock_file, JSON.generate(data)) end |
#lock_info(project, destination = nil) ⇒ Object
79 80 81 82 83 84 |
# File 'lib/harbor/deploy_lock.rb', line 79 def lock_info(project, destination = nil) lock_file = lock_path(project, destination) return nil unless File.exist?(lock_file) JSON.parse(File.read(lock_file)) end |
#locked?(project, destination = nil) ⇒ Boolean
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/harbor/deploy_lock.rb', line 51 def locked?(project, destination = nil) lock_file = lock_path(project, destination) return false unless File.exist?(lock_file) data = JSON.parse(File.read(lock_file)) lock_time = Time.parse(data["timestamp"]) if Time.now.utc - lock_time > @timeout File.delete(lock_file) return false end # Check if PID is still alive if data["pid"] begin Process.kill(0, data["pid"]) rescue Errno::ESRCH # Process is dead, stale lock File.delete(lock_file) return false rescue Errno::EPERM # Process exists but we can't signal it — lock is valid end end true end |
#refresh(project:, destination: nil) ⇒ Object
42 43 44 45 46 47 48 49 |
# File 'lib/harbor/deploy_lock.rb', line 42 def refresh(project:, destination: nil) lock_file = lock_path(project, destination) return unless File.exist?(lock_file) data = JSON.parse(File.read(lock_file)) data["timestamp"] = Time.now.utc.iso8601 File.write(lock_file, JSON.generate(data)) end |
#release(project:, destination: nil) ⇒ Object
37 38 39 40 |
# File 'lib/harbor/deploy_lock.rb', line 37 def release(project:, destination: nil) lock_file = lock_path(project, destination) File.delete(lock_file) if File.exist?(lock_file) end |