Class: Collavre::ChannelAttacher

Inherits:
Object
  • Object
show all
Defined in:
app/services/collavre/channel_attacher.rb

Overview

Shared idempotent attach/reactivate lifecycle for topic channels. Every channel subtype reaches the same end-state regardless of which tool invoked it: a row that is active, not dismissed, and visible under the ‘not_dismissed` render scope.

Subtype-specific resets (e.g. PR ‘pr_state` back to “open” so a previously merged-then-reattached channel renders the green badge again) run via the `on_reactivate` proc.

Class Method Summary collapse

Class Method Details

.call(channel_class:, lookup:, create_attrs:, on_reactivate: nil, on_noop: nil) ⇒ Object

Returns [channel, status] where status ∈ :created / :reactivated / :noop.

‘lookup` is called twice in the unique-violation race path, so it must be a fresh query each call (not a captured AR record).

‘on_noop` runs when the existing channel is still active+visible and we would otherwise short-circuit. Preview channels use it to silently refresh config (e.g. new port after a restart) so the chip link never points at a dead server while reporting success.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/services/collavre/channel_attacher.rb', line 22

def self.call(channel_class:, lookup:, create_attrs:, on_reactivate: nil, on_noop: nil)
  existing = lookup.call
  if existing
    return noop(existing, on_noop) if existing.active? && existing.dismissed_at.nil?
    reactivate(existing, on_reactivate)
    return [ existing, :reactivated ]
  end
  [ channel_class.create!(create_attrs), :created ]
rescue ActiveRecord::RecordNotUnique
  existing = lookup.call
  raise unless existing
  if existing.active? && existing.dismissed_at.nil?
    noop(existing, on_noop)
  else
    reactivate(existing, on_reactivate)
    [ existing, :reactivated ]
  end
end