Module: RoundhouseUi::Snapshots

Defined in:
lib/roundhouse_ui/snapshots.rb

Overview

Back up a queue's jobs before you purge it, and restore them later — the safety net that makes clearing a stuck queue non-destructive.

Storage is pluggable via RoundhouseUi.snapshot_store. The default RedisStore keeps blobs in Redis (simple, dependency-free); for large/stuck queues you'll want a file or S3 store so the backup doesn't sit in the same Redis you're trying to relieve. Any object responding to write/read/delete/ids works.

Defined Under Namespace

Classes: RedisStore

Class Method Summary collapse

Class Method Details

.allObject



32
33
34
# File 'lib/roundhouse_ui/snapshots.rb', line 32

def all
  store.ids.filter_map { |id| (id) }.sort_by { |m| -m[:created_at].to_f }
end

.delete(id) ⇒ Object



55
56
57
# File 'lib/roundhouse_ui/snapshots.rb', line 55

def delete(id)
  store.delete(id)
end

.metadata(id) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/roundhouse_ui/snapshots.rb', line 36

def (id)
  raw = store.read(id)
  return nil unless raw

  data = JSON.parse(raw)
  { id: id, queue: data["queue"], count: data["count"] || data["jobs"].size, created_at: data["created_at"] }
end

.restore(id) ⇒ Object

Re-enqueue a snapshot's jobs onto their original queue. Returns the count.



45
46
47
48
49
50
51
52
53
# File 'lib/roundhouse_ui/snapshots.rb', line 45

def restore(id)
  raw = store.read(id)
  return 0 unless raw

  data = JSON.parse(raw)
  key = "queue:#{data["queue"]}"
  data["jobs"].each { |payload| Sidekiq.redis { |conn| conn.call("RPUSH", key, payload) } }
  data["jobs"].size
end

.storeObject



15
16
17
# File 'lib/roundhouse_ui/snapshots.rb', line 15

def store
  RoundhouseUi.snapshot_store
end

.take(queue_name) ⇒ Object

Copy every job currently on queue_name into a snapshot. Non-destructive — the queue is left untouched (purge separately if you want to clear it).



21
22
23
24
25
26
27
28
29
30
# File 'lib/roundhouse_ui/snapshots.rb', line 21

def take(queue_name)
  payloads = []
  Sidekiq::Queue.new(queue_name).each { |job| payloads << job.value }

  id = "#{queue_name}-#{Time.now.to_i}-#{rand(10_000)}"
  store.write(id, JSON.dump(
    "queue" => queue_name, "created_at" => Time.now.to_f, "count" => payloads.size, "jobs" => payloads
  ))
  (id)
end