I have the following code using Eventmachine, Faye Websockets and RestClient:
class FxApi
def self.rates(base_currency = 'USD')
JSON.parse Restclient.get(FX_API_URL + '/latest', { base: base_currency })
end
end
class ReportingApi
def self.add_quote(payload)
RestClient.post(REPORTING_API_URL + '/quote', payload)
end
end
rates = {}
EM.run do
# Keep updating currency rates every 10 seconds
EM.add_periodic_timer(10) do
rates = FxApi.latest
end
ws = Faye::WebSocket::Client.new('wss://ws.stock.com')
ws.on :open do |event|
ws.send({ event: 'subscribe', subscription: { name: 'quotes' } }.to_json)
end
ws.on :message do |event|
data = JSON.parse(event.data)
ReportingApi.add_quote(data)
if data['event'] == 'quote'
price_in_usd = data['price'] / rates[data['currency']]
if price_in_usd < 100
ws.send({ event: 'addOrder', params: { side: 'buy', qty: 1, type: 'market' } }.to_json)
end
end
end
end
I want to make sure that all "slow" tasks (ie. web requests) within the EM are non-blocking, so that they don't slow down the whole EM loop.
- Is the Faye
ws.sendblocking? If yes, how to make it non-blocking? - How to make
FxApi.latestnon-blocking? Can you just doThread.new { rates = FxApi.latest }or is it more complicated? - Anything else that should be considered?
I'm still relatively new to Eventmachine and honestly a bit confused how Ruby's standard threads, the EM way (EM.next_tick, EM.defer, etc.), RestClient adaptors and EM tailored HTTP client solutions (such as https://github.com/igrigorik/em-http-request) all relate to each other.
Are there any production quality open-source projects or comprehensive guides that would help to get a sense of the common patterns?