class React::Rails::HotLoader::Server

Attributes

change_set_class[R]
host[R]
port[R]

Public Class Methods

new(host: "0.0.0.0", port:, change_set_class: React::Rails::HotLoader::AssetChangeSet) click to toggle source
# File lib/hot_loader/server.rb, line 9
def initialize(host: "0.0.0.0", port:, change_set_class: React::Rails::HotLoader::AssetChangeSet)
  @host = host
  @port = port
  @change_set_class = change_set_class
  @processed_msg = Hash.new
end

Public Instance Methods

restart() click to toggle source

Restarts the server if it has stopped

# File lib/hot_loader/server.rb, line 17
def restart
  start
rescue StandardError => err
  if err.message =~ /no acceptor/
    React::Rails::HotLoader.log("WS server is already running (#{ws_url})")
  else
    React::Rails::HotLoader.error(err)
  end
end

Private Instance Methods

already_has_event_machine_server?() click to toggle source
# File lib/hot_loader/server.rb, line 80
def already_has_event_machine_server?
  defined?(Thin)
end
handle_message(ws, msg) click to toggle source

Check for any changes since `msg`, respond if there are any changes, skip if msg was already processed (queue issue)

# File lib/hot_loader/server.rb, line 42
def handle_message(ws, msg)
  # React::Rails::HotLoader.log("received message: #{msg}")
  return true if @processed_msg[ws.signature] == msg
  since_time =  Time.at(msg.to_i)
  changes = change_set_class.new(since: since_time)
  if changes.bankrupt?
    changed_files_count = changes.changed_file_names.length
    React::Rails::HotLoader.log("declared bankruptcy! (#{changed_files_count} files changed)")

    bankruptcy_response = {
      bankrupt: true,
      changed_files_count: changed_files_count,
    }

    ws.send(bankruptcy_response.to_json)
  elsif changes.any?
    React::Rails::HotLoader.log("sent changes: #{changes.changed_file_names}")
    ws.send(changes.to_json)
    @processed_msg[ws.signature] = msg
  end
rescue StandardError => err
  React::Rails::HotLoader.error(err)
end
run_websocket_server() click to toggle source
# File lib/hot_loader/server.rb, line 66
def run_websocket_server
  ws_url =  "ws://#{host}:#{port}"
  React::Rails::HotLoader.log("starting WS server (#{ws_url})")

  EM::WebSocket.run(host: host, port: port) do |ws|
    ws.onopen     { React::Rails::HotLoader.log("opened a connection (#{ws_url})") }
    ws.onmessage  { |msg| handle_message(ws, msg) }
    ws.onclose    { React::Rails::HotLoader.log("closed a connection (#{ws_url})") }
  end

  React::Rails::HotLoader.log("started WS server (#{ws_url})")

end
start() click to toggle source

If the Rails server runs event machine already, don't run EventMachine again, instead hook in with `next_tick`

# File lib/hot_loader/server.rb, line 31
def start
  if already_has_event_machine_server?
    EM.next_tick { run_websocket_server }
  else
    Thread.new do
      EM.run { run_websocket_server }
    end
  end
end