Skip to content

Instantly share code, notes, and snippets.

@morhekil
Created October 8, 2016 14:10
Show Gist options
  • Save morhekil/00b078258392da4288d607ec9dd3efc4 to your computer and use it in GitHub Desktop.
Save morhekil/00b078258392da4288d607ec9dd3efc4 to your computer and use it in GitHub Desktop.
TCPSocket based implementation of ServerRenderingPool for react-on-rails, with safe error handling and auto-reconnect

This is an implementation of ServerRenderingPool for react-on-rails that connects to NodeJS process over a TCP socket, instead of a UNIX socket.

The code handles socket disconnections, and attempts to reestablish connection to NodeJS server process in these cases. Also, if a connection-related exception was caught, it will not raise an exception in Rails server, but report it to Airbrake and return empty result - to let standard front-end code deal run its course.

The should be placed into an initializer (e.g. config/initializers/react_on_rails.rb), and its configuration block expanded with your usual configuration.

module ReactOnRails
class Configuration
attr_accessor :server_addr, :server_port
end
module ServerRenderingPool
class << self
# Let configuration specify a server render method class itself,
# instead of its symbolic name
def pool
ReactOnRails.configuration.server_render_method
end
end
class NodeTCP < Node
def self.server_render_js_with_console_logging(*args)
super(*args)
rescue SystemCallError, JSON::ParserError => e
# If JS evaluation failed - reset the connection pool, expecting
# a system call error or a malformed response only when
# when there's a problem with NodeJS process connection
reset_pool
Airbrake.notify_or_ignore e
{ 'html' => '',
'consoleReplayScript' => "<script>console.log('#{e}')</script>" }
end
class << self
private
# TCPSocket based js context connection
def create_js_context
cfg = ReactOnRails.configuration
TCPSocket.new(cfg.server_addr, cfg.server_port).tap do |c|
c.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
end
end
end
end
end
end
ReactOnRails.configure do |config|
# NodeTCP pool parameters
config.server_render_method = ReactOnRails::ServerRenderingPool::NodeTCP
config.server_addr = '127.0.0.1'
config.server_port = ENV['NODE_RENDER_PORT'].to_i
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment