Class: Sidekiq::Deploy

Inherits:
Object
  • Object
show all
Defined in:
lib/sidekiq/deploy.rb

Constant Summary collapse

MARK_TTL =

90 days

90 * 24 * 60 * 60
LABEL_MAKER =
-> {
  `git log -1 --format="%h %s"`.strip
}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pool = Sidekiq::RedisConnection.create) ⇒ Deploy

Returns a new instance of Deploy.



29
30
31
# File 'lib/sidekiq/deploy.rb', line 29

def initialize(pool = Sidekiq::RedisConnection.create)
  @pool = pool
end

Class Method Details

.mark!(label = nil) ⇒ Object



25
26
27
# File 'lib/sidekiq/deploy.rb', line 25

def self.mark!(label = nil)
  Sidekiq::Deploy.new.mark!(label: label)
end

Instance Method Details

#fetch(date = Time.now.utc.to_date) ⇒ Object



59
60
61
62
# File 'lib/sidekiq/deploy.rb', line 59

def fetch(date = Time.now.utc.to_date)
  datecode = date.strftime("%Y%m%d")
  @pool.with { |c| c.hgetall("#{datecode}-marks") }
end

#mark!(at: Time.now, label: nil) ⇒ Object



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
# File 'lib/sidekiq/deploy.rb', line 33

def mark!(at: Time.now, label: nil)
  label ||= LABEL_MAKER.call
  # we need to round the timestamp so that we gracefully
  # handle an very common error in marking deploys:
  # having every process mark its deploy, leading
  # to N marks for each deploy. Instead we round the time
  # to the minute so that multiple marks within that minute
  # will all naturally rollup into one mark per minute.
  whence = at.utc
  floor = Time.utc(whence.year, whence.month, whence.mday, whence.hour, whence.min, 0)
  datecode = floor.strftime("%Y%m%d")
  key = "#{datecode}-marks"
  stamp = floor.iso8601

  @pool.with do |c|
    # only allow one deploy mark for a given label for the next minute
    lock = c.set("deploylock-#{label}", stamp, "nx", "ex", "60")
    if lock
      c.multi do |pipe|
        pipe.hsetnx(key, stamp, label)
        pipe.expire(key, MARK_TTL)
      end
    end
  end
end