Module: Wurk::Api::Serializers

Defined in:
app/controllers/wurk/api/serializers.rb

Overview

Pure mapping from inspector objects → JSON-shaped Hashes for the dashboard SPA. Keeping the serializers out of the controller lets the action methods stay tiny and lets future endpoints share the same field shapes without re-implementing them.

Class Method Summary collapse

Class Method Details

.cron_row(loop_obj, now_epoch) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'app/controllers/wurk/api/serializers.rb', line 98

def cron_row(loop_obj, now_epoch)
  {
    lid: loop_obj.lid,
    schedule: loop_obj.schedule,
    klass: loop_obj.klass,
    queue: loop_obj.queue,
    tz: loop_obj.tz_name,
    paused: loop_obj.paused?,
    args: loop_obj.args,
    last_fire_at: loop_obj.last_fired_at,
    next_fire_at: loop_obj.next_fire_at(now_epoch)
  }
end

.history_point(row) ⇒ Object

One point in a cluster-total time-series (Wurk::Metrics::Query.history). ‘at` is epoch seconds at the bucket start.



118
119
120
# File 'app/controllers/wurk/api/serializers.rb', line 118

def history_point(row)
  { at: row[:at], processed: row[:p], failed: row[:f], runtime_ms: row[:ms] }
end

.job_record(record) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'app/controllers/wurk/api/serializers.rb', line 37

def job_record(record)
  {
    jid: record.jid,
    klass: record.display_class,
    args: record.display_args,
    queue: record.queue,
    enqueued_at: record.enqueued_at&.to_f,
    created_at: record.created_at&.to_f
  }
end

.limiter_row(name, meta) ⇒ Object



77
78
79
80
81
82
83
84
85
# File 'app/controllers/wurk/api/serializers.rb', line 77

def limiter_row(name, meta)
  {
    name: name,
    type: meta['type'].to_s,
    fingerprint: meta['fingerprint'].to_s,
    options: parse_options(meta['options']),
    status: limiter_status(name, meta)
  }
end

.limiter_status(name, meta) ⇒ Object

Reconstruct the limiter (read-only, ‘register: false`) just to read its uniform `{ used, limit, reset_at, available? }` status for the Limits tab. Best-effort: a malformed meta hash yields nil rather than 500-ing the whole list.



91
92
93
94
95
96
# File 'app/controllers/wurk/api/serializers.rb', line 91

def limiter_status(name, meta)
  limiter = ::Wurk::Limiter.build(name, meta['type'], parse_options(meta['options']))
  limiter&.status
rescue StandardError
  nil
end

.metric_row(klass, totals) ⇒ Object



112
113
114
# File 'app/controllers/wurk/api/serializers.rb', line 112

def metric_row(klass, totals)
  { klass: klass, processed: totals[:p], failed: totals[:f], runtime_ms: totals[:ms] }
end

.parse_options(raw) ⇒ Object



122
123
124
125
126
127
128
# File 'app/controllers/wurk/api/serializers.rb', line 122

def parse_options(raw)
  return {} if raw.nil? || raw.to_s.empty?

  ::JSON.parse(raw)
rescue ::JSON::ParserError
  {}
end

.process_row(process) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'app/controllers/wurk/api/serializers.rb', line 58

def process_row(process)
  {
    identity: process.identity,
    hostname: process['hostname'],
    pid: process['pid'],
    tag: process.tag,
    concurrency: process['concurrency'],
    busy: process['busy'],
    beat: process['beat'],
    quiet: process.stopping?,
    rss: process['rss'],
    rtt_us: process['rtt_us'],
    labels: process.labels,
    queues: process.queues,
    version: process.version,
    embedded: process.embedded?
  }
end

.queue_summary(summary) ⇒ Object



33
34
35
# File 'app/controllers/wurk/api/serializers.rb', line 33

def queue_summary(summary)
  { name: summary.name, size: summary.size, latency: summary.latency, paused: summary.paused? }
end

.sorted_entry(entry) ⇒ Object



48
49
50
51
52
53
54
55
56
# File 'app/controllers/wurk/api/serializers.rb', line 48

def sorted_entry(entry)
  job_record(entry).merge(
    score: entry.score,
    at: entry.at.to_f,
    error_class: entry['error_class'],
    error_message: entry['error_message'],
    retry_count: entry['retry_count']
  )
end

.stats_payload(stats) ⇒ Object

Wire-shape consumed by the React dashboard’s landing page + SSE feed. Field names match the SPA’s ‘StatsSnapshot` interface in frontend/src/hooks/useSSE.ts — keep them in sync. The canonical Sidekiq-compatible accessors on Wurk::Stats use `_size` suffixes; this serializer renames them for the dashboard’s wire shape only.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'app/controllers/wurk/api/serializers.rb', line 17

def stats_payload(stats)
  {
    processed: stats.processed,
    failed: stats.failed,
    expired: stats.expired,
    enqueued: stats.enqueued,
    busy: stats.workers_size,
    scheduled: stats.scheduled_size,
    retries: stats.retry_size,
    dead: stats.dead_size,
    processes: stats.processes_size,
    latency: stats.default_queue_latency,
    queues: stats.queue_summaries.map { |q| queue_summary(q) }
  }
end