Skip to content

Instantly share code, notes, and snippets.

@scalaview
Created November 15, 2017 09:28
Show Gist options
  • Save scalaview/d37a46dee2947c2f11d4070db2c6360d to your computer and use it in GitHub Desktop.
Save scalaview/d37a46dee2947c2f11d4070db2c6360d to your computer and use it in GitHub Desktop.
module LivingsmartApi
module Rpc
class Callback
def initialize(response)
@response = response
end
end
end
end
module LivingsmartApi
module Rpc
class Logic
attr_accessor :res
def initialize(url, callback, channel)
@redis = Redis.new(url: url)
@res = Response.new(@redis, channel)
@callback = callback.new(@res)
end
def exec(args)
_method, _params = args.split(':', 2)
raise(ArgumentError, "miss method name") if _method.blank?
begin
params = JSON.parse(_params)
@callback.send(_method.strip, *params)
rescue Exception => e
@res.catch(e)
end
end
end
end
end
module LivingsmartApi
module Rpc
class Response
def initialize(redis, channel)
@redis = redis
@channel = channel
end
def publish(_method, params)
@redis.publish(@channel, "#{_method}:#{params.to_json}")
end
def catch(e)
@redis.publish("exception", e.message.to_s)
end
def method_missing(m, *args)
publish(m, args)
end
end
end
end
module LivingsmartApi
module Rpc
class Server
def initialize(url, subscribe_channel, callback_channel, callback=Callback)
@redis = Redis.new(url: url)
@subscribe_channel = subscribe_channel
@logic = Logic.new(url, callback, callback_channel)
exec
end
def exec
@thread = Thread.new do
begin
@redis.subscribe(@subscribe_channel, :exception) do |on|
on.subscribe do |channel, subscriptions|
Rails.logger.info("Subscribed to ##{channel} (#{subscriptions} subscriptions)")
end
on.message do |channel, args|
Rails.logger.info("##{channel}: #{args}")
# name:array
case channel.to_sym
when :exception
Rails.logger.error("exception: #{args}")
else
begin
@logic.exec(args)
rescue Exception => e
Rails.logger.error(e.message.to_s)
end
end
end
on.unsubscribe do |channel, subscriptions|
Rails.logger.info("Unsubscribed from ##{channel} (#{subscriptions} subscriptions)")
end
end
rescue Redis::BaseConnectionError => error
puts "#{error}, retrying in 30s"
sleep 30
retry
end
end
end
def client
@logic.res
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment