Database vs in-memory?

201 views
Skip to first unread message

Nytz12

unread,
Nov 30, 2015, 8:49:59 PM11/30/15
to elixir-lang-talk
Hi

I am building a matchmaking mechanism. Player can enter the matchmaking queue, and as soon as two people are in the queue, a 'gameroom' is created for both users, and they're removed from the queue.

My question is whether it's best to represent this queue on the database level, say, each time a user joins, a record is created in the database, and then I periodically poll the records. Or, if it's better to implement using for example a genserver to hold the queue in memory?

What are the pros/cons with regards to fault-tolerance, performance and resource overhead?

Redvers Davies

unread,
Dec 1, 2015, 2:17:41 AM12/1/15
to elixir-l...@googlegroups.com
tl;dr:
Given the simplicity of the request anything other than a GenServer seems overkill.

  def handle_call(:got_partner?, {pid, _ref}, nil), do: {:reply, :ok, pid}

  def handle_call(:got_partner?, {pid, _ref}, pid), do: {:reply, :ok, pid}

  def handle_call(:got_partner?, {pid, _ref}, waiting) when is_pid(waiting) do
    Supervisor.start_child(App.GameServer.Supervisor, [waiting, pid])
    {:reply, :ok, nil}
  end


Looking at my code your first question may be to ask why I would have a "Puritan Clause"[tm] to prevent a player from playing with themselves[0].

To defend against a player getting orphaned if they're in the queue and the MatchMaker GenServer (above) crashes I would put an :erlang.send_event call in the Player GenServer to re-submit them every 10 seconds until they've been moved into a game.  The "Puritan Clause"[tm] ensures that if a different player doesn't arrive in those 10 seconds they're not dispatched to play with themselves.


Now for the "too long"[1]:

There are many ways to skin this cat.  I'm hoping you get a variety of answers.  Here's mine from the point of view of someone who has a very high bar that must be met before I consider adding an RDBMS.

With an RDBMS you gain:
  1. Persistence
  2. Easy visibility of data for other tools via SQL.

You also gain:

  1. An external dependency that doesn't use the same failure characteristics as the beam.
  2. Latency.
  3. Additional complexity in deployment.
This certainly isn't a significant enough requirement in my mind to reach for an RDBMS but if you're using it for something else in your application then the bar has already been met.  But should you still use it even if it's there already?

The way you describe your matchmaking process it sounds as simple as "is there anyone in the queue already?" so that's what I implemented.  I explicitly chose to serialize requests __because it's a queue__ and our actions upon it need to be atomic.  To make those atomic you need to do transactions on a single column single row table.  This will serialize all your requests __outside of your control__.

Naturally, if your requirements became more complex or you're needing to interoperate with other applications written in other languages an RDBMS may make more sense.  Apart from having to match based on criteria that already exists in a database from long queue lengths I can't think of any good reason to use it.  Nope, even with that I still can't.  Others on the list may...

ETS is another option which would allow the player GenServers to "self-organize".  Far more complex in my view.

If you want to talk about the scenario where you have multiple systems in a cluster which are geographically distributed and you want to deal with network partitioning then I'd be looking at :gproc.  You'd want to try in the main to keep your players in the same systems / regions as much as possible so additional metadata like that would be useful in your decision making.

Thanks,



Red
[0] Gender neutral singular form.  It has both singular and plural usage - check the OED. [2]
[1] It started too long, then I edited it.
[2] All footnotes should start at 0.


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/07eb1718-b09f-4ab4-bbdc-660bdb2c73ab%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Torben Hoffmann

unread,
Dec 1, 2015, 6:01:46 PM12/1/15
to elixir-l...@googlegroups.com
I actually designed a stock exchange using processes - albeit in Erlang:

Basic idea is to broadcast your desire to all interested parties (pub/sub) and make sure you are subscribed to the relevant "channels".

My solution might require a bit of thinking about what to do if you receive a matching proposal while negotiating a match with another party, but I think you could solve that by re-broadcasting your intent after an un-successful negotiation.

And match making is simpler than a stock exchange because you only have one item to "trade".

Cheers,
Torben


For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages