Given Ecto is Poolboy with a GenServer that talks to the database, I would expect the second try to be reasonably faster than Ecto, unless the action your GenServer is performing is horribly slow. Can you link to the GenServer code?
If you are using one HTTP library, make sure it doesn't have its own pool as well and, if it does, make sure it has a reasonable size.
Also look at the Poolboy configuration, like pool size and overflow and play with different configurations.
Finally, when stress testing, run :observer.start and see if you can identify in the process tab which process is getting behind, that is likely going to be your bottleneck.
--
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/CAGnRm4K8OJ9jNsoEednsbynx3_8f5xxzhfMs8axvc8317tP7oA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
Sorry, I meant the third case should be ok. I will take a deeper look soon but why have you moved the database access inside the GenServer then?
You should try to avoid making blocking calls inside a GenServer because as you stated it serializes requests.One useful technique that I'm using in rethinkdb-elixir is using :noreply in handle_call and the replying later.You can see an example at https://github.com/hamiltop/rethinkdb-elixir/blob/master/lib/rethinkdb/connection.exYou could, for example, launch a Task in handle_call, return :noreply, and then in handle_info you can wait for the Task to send its response and then use GenServer.reply to send the result. Something like:def handle_call({:get_by_token, token}, from, tasks) dot = Task.async(fn -> get_by_token(token) end){:no_reply, Map.put_new(tasks, t.ref, from)}enddef handle_info({ref, result}, tasks) when is_reference(ref) doGenServer.reply(tasks[ref], result){:noreply, Map.delete(tasks, ref)}end
That's fairly simplistic, but I'd be curious to see your benchmark with such an implementation.
Running 30s test @ http://127.0.0.1:8880/user/
10 threads and 400 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.15s 143.86ms 1.32s 91.60%
Req/Sec 35.93 23.85 141.00 66.98%
10105 requests in 30.08s, 3.18MB read
Socket errors: connect 0, read 247, write 0, timeout 0
Requests/sec: 335.98
Transfer/sec: 108.27KB
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/b3a4040a-a810-40e6-bfb1-9094c0e5ba5e%40googlegroups.com.
The more I think about this, I have the feeling that the GenServer is really not what we want, maybe I should check again erlang RPC.
:rpc.call(:some_node@foo, Calculator, :add, [1, 2])