0

I'm building a server on Ruby using WebSockets through EventMachine.

Let's say user Carl asks for a Car.

The car of id "7" is requested to the CarManager. CarManager creates a Car instance, Car loads itself from a Mongo Database (id was provided). Car "7" is stored in CarManager, like a cache, as long Carl or anyone else keeps using or requesting it. And then Car is sent through WebSocket, specifically to Carl. I stored Carl's WS somewhere.

What if two users, say, Lenny and Carl, both ask for Car id "7" at the "exact" same time. Will CarManager, because it can't find in either case a cached version of Car 7, fetch it both times from database and instantiate it, or ONE of these two WebSocket request will be processed first, and then the second one will use the cached version?

The whole asynchronous thing of WebSockets made me a bit confused. Thank you for any insights on this!

ArtPulse
  • 365
  • 4
  • 16

2 Answers2

0

Let me put it this way: imagine you have scaled to two servers. You should get the idea that your approach to lazy Car creation is incorrect. You should not allow users create using a provided id, or you should use some external mutex, for example "Car:7:loading" in CarManager. Or, alternatively, you can make your CarManager a transparent proxy, putting the job fetching Cars on it (and facing the same concurrent issues there).

phil pirozhkov
  • 4,740
  • 2
  • 33
  • 40
0

I'd use something like Mongoid to hide most of those details, so that when Carl's browser sends a websocket onmessage request like {:command => 'get_car", :car_id => "7"} your EM's onmessage handler would look a bit like

ws.onmessage do |msg|
  message = JSON.parse(msg)
  car = Cars.where(car_number: message[:car_id]).first
  ws.send(car.to_json)
end

obviously you'd want to handle the case where the car is not found, or the message is improperly formed, etc, and you might want to customise the JSON returned a bit (add a .to_summary method for example to the Car model) so it only returns the info about the car that the client cares about.

You needn't worry about which request comes in first, or even if they both come in at the same time as mongoid will handle that low level stuff for you.

Dave Sag
  • 13,266
  • 14
  • 86
  • 134