Non-blocking Faye Websocket + Eventmachine + RestClient

161 Views Asked by At

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.

  1. Is the Faye ws.send blocking? If yes, how to make it non-blocking?
  2. How to make FxApi.latest non-blocking? Can you just do Thread.new { rates = FxApi.latest } or is it more complicated?
  3. 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?

0

There are 0 best solutions below