Class: Solrengine::Realtime::AccountMonitor

Inherits:
Object
  • Object
show all
Defined in:
lib/solrengine/realtime/account_monitor.rb

Overview

Subscribes to Solana WebSocket RPC for real-time account changes. When an account changes, dispatches to all registered subscribers via Solrengine::Realtime.dispatch.

Constant Summary collapse

SOLANA_ADDRESS_REGEX =
/\A[1-9A-HJ-NP-Za-km-z]{32,44}\z/
RECONNECT_DELAY =
5
BROADCAST_DELAY =
3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(wallet_address) ⇒ AccountMonitor

Returns a new instance of AccountMonitor.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/solrengine/realtime/account_monitor.rb', line 17

def initialize(wallet_address)
  unless wallet_address.is_a?(String) && wallet_address.match?(SOLANA_ADDRESS_REGEX)
    raise ArgumentError, "Invalid Solana wallet address"
  end

  @wallet_address = wallet_address.freeze
  @ws_url = Solrengine::Rpc.configuration.ws_url

  unless @ws_url&.start_with?("wss://")
    logger.warn("[SolanaWS] WebSocket URL does not use wss:// (TLS) — connection is unencrypted")
  end

  @running = false
  @subscription_id = nil
  @account_changed = false
  @mutex = Mutex.new
  @cv = ConditionVariable.new
end

Instance Attribute Details

#wallet_addressObject (readonly)

Returns the value of attribute wallet_address.



15
16
17
# File 'lib/solrengine/realtime/account_monitor.rb', line 15

def wallet_address
  @wallet_address
end

Instance Method Details

#flag_changed!Object



58
59
60
61
62
63
# File 'lib/solrengine/realtime/account_monitor.rb', line 58

def flag_changed!
  @mutex.synchronize do
    @account_changed = true
    @cv.signal
  end
end

#loggerObject



65
66
67
# File 'lib/solrengine/realtime/account_monitor.rb', line 65

def logger
  @logger ||= defined?(Rails) ? Rails.logger : Logger.new($stdout, progname: "SolanaWS")
end

#running?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/solrengine/realtime/account_monitor.rb', line 54

def running?
  @running
end

#startObject



36
37
38
39
40
41
42
# File 'lib/solrengine/realtime/account_monitor.rb', line 36

def start
  return if @running
  @running = true

  @ws_thread = Thread.new { websocket_loop }
  @broadcast_thread = Thread.new { broadcast_loop }
end

#stopObject



44
45
46
47
48
49
50
51
52
# File 'lib/solrengine/realtime/account_monitor.rb', line 44

def stop
  @running = false
  @cv.signal
  @ws&.close rescue nil
  @ws_thread&.join(5)
  @broadcast_thread&.join(5)
  @ws_thread = nil
  @broadcast_thread = nil
end