Class: Mbeditor::EditorChannel

Inherits:
CableBaseClass
  • Object
show all
Includes:
ChannelAuthentication
Defined in:
app/channels/mbeditor/editor_channel.rb

Instance Method Summary collapse

Methods included from ChannelAuthentication

#mbeditor_authenticated?

Instance Method Details

#presence(data) ⇒ Object

Presence heartbeat: record this participant and broadcast the whole roster.

Whole roster, not just the sender: clients replace theirs outright, so they cannot accumulate a participant the server has already dropped. That is the one guarantee per-participant events could not give, and it also removes the client-side merge, the leave handling and the greet-a-new-peer re-announce that used to stand in for it.



44
45
46
47
48
# File 'app/channels/mbeditor/editor_channel.rb', line 44

def presence(data)
  @presence_client_id = data["client_id"]
  PresenceRegistry.record(@presence_client_id, data)
  relay(presence_payload)
end

#save_branch_state(data) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# File 'app/channels/mbeditor/editor_channel.rb', line 57

def save_branch_state(data)
  branch = data["branch"].to_s.strip
  state  = data["state"]
  EditorStateService.new(workspace_root).write_branch_state(branch, state)
rescue EditorStateService::InvalidBranchError
  # A misbehaving client sent a malformed branch name. Don't crash the
  # connection, but log it so the misconfiguration is observable.
  Rails.logger.warn("[mbeditor] EditorChannel#save_branch_state: rejected invalid branch name #{branch.inspect}")
rescue StandardError
  # Never let a state-save failure crash the WebSocket connection
end

#save_state(data) ⇒ Object



50
51
52
53
54
55
# File 'app/channels/mbeditor/editor_channel.rb', line 50

def save_state(data)
  state = data["state"] || data
  EditorStateService.new(workspace_root).write_state(state)
rescue StandardError
  # Never let a state-save failure crash the WebSocket connection
end

#start_log_tail(data) ⇒ Object



69
70
71
72
73
# File 'app/channels/mbeditor/editor_channel.rb', line 69

def start_log_tail(data)
  raw = data && data["offset"]
  @log_offset = raw.nil? ? nil : raw.to_i
  @log_watching = true
end

#stop_log_tail(_data = nil) ⇒ Object



75
76
77
# File 'app/channels/mbeditor/editor_channel.rb', line 75

def stop_log_tail(_data = nil)
  @log_watching = false
end

#subscribedObject



12
13
14
15
16
17
18
19
20
# File 'app/channels/mbeditor/editor_channel.rb', line 12

def subscribed
  return unless mbeditor_authenticated?

  stream_from "mbeditor_editor" if respond_to?(:stream_from)
  # Hand the joiner the current roster straight away. Without it they would
  # only learn about a peer who happens to heartbeat after they connected,
  # and would show an empty participant list until then.
  transmit(presence_payload) if respond_to?(:transmit, true)
end

#unsubscribedObject



27
28
29
30
31
32
33
34
35
# File 'app/channels/mbeditor/editor_channel.rb', line 27

def unsubscribed
  # Action Cable calls this on a clean close *and* on its own connection
  # timeout, which is what makes the registry authoritative: a participant
  # cannot linger past their socket.
  return if @presence_client_id.nil?

  PresenceRegistry.remove(@presence_client_id)
  relay(presence_payload)
end