Class: FastMcpPubsub::Service

Inherits:
Object
  • Object
show all
Defined in:
lib/fast_mcp_pubsub/service.rb

Overview

Core PostgreSQL NOTIFY/LISTEN service for broadcasting MCP messages across Puma workers

Constant Summary collapse

MAX_PAYLOAD_SIZE =

PostgreSQL NOTIFY limit is 8000 bytes, leave some margin

7800

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.listener_threadObject (readonly)

Returns the value of attribute listener_thread.



9
10
11
# File 'lib/fast_mcp_pubsub/service.rb', line 9

def listener_thread
  @listener_thread
end

Class Method Details

.broadcast(message) ⇒ Object



11
12
13
14
15
16
17
18
# File 'lib/fast_mcp_pubsub/service.rb', line 11

def broadcast(message)
  payload = message.to_json

  payload_too_large?(payload) ? send_error_response(message, payload) : send_payload(payload)
rescue StandardError => e
  FastMcpPubsub.logger.error "FastMcpPubsub: Error broadcasting message: #{e.message}"
  raise
end

.start_listenerObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/fast_mcp_pubsub/service.rb', line 20

def start_listener
  unless FastMcpPubsub.config.enabled
    FastMcpPubsub.logger.info "FastMcpPubsub: Not starting listener - disabled in config for PID #{Process.pid}"
    return
  end

  if @listener_thread&.alive?
    FastMcpPubsub.logger.info "FastMcpPubsub: Listener already running for PID #{Process.pid}"
    return
  end

  FastMcpPubsub.logger.info "FastMcpPubsub: Starting listener thread for PID #{Process.pid}"

  @listener_thread = Thread.new do
    Thread.current.name = "fast-mcp-pubsub-listener"
    listen_loop
  end

  # Register shutdown hook
  at_exit { stop_listener }
end

.stop_listenerObject



42
43
44
45
46
47
48
49
# File 'lib/fast_mcp_pubsub/service.rb', line 42

def stop_listener
  return unless @listener_thread&.alive?

  FastMcpPubsub.logger.info "FastMcpPubsub: Stopping listener thread for PID #{Process.pid}"
  @listener_thread.kill
  @listener_thread.join(5) # Wait max 5 seconds
  @listener_thread = nil
end