[erlang-questions] Cowboy (Erlang) VS Haskell (Warp)

Knut Nesheim <>
Thu Jun 27 11:17:00 CEST 2013


I agree that having a web request process be "debuggable" using the sys
module can be quite useful. So far no users of Elli has told me of such a
wish. For myself and the users of Elli I know of, process_info/2 has been
very helpful in debugging the web request processes.

If you want a webserver that strictly follows the OTP principles, maybe you
should use Cowboy. There are both pros and cons with doing so and as is
pretty obvious, people have different views of the tradeoffs. Some might
think it is an absolute requirement to strictly follow the OTP principles,
others might think there are cases when it doesn't make much sense.

Elli is not meant to be everything to everybody. If you find it hard to
debug Elli, cursing my name is misplacing your anger and won't help you
achieve anything. I happily help anybody who comes to me with questions.

Knut


On Wed, Jun 26, 2013 at 4:48 PM, Loïc Hoguin <> wrote:

> They are not short lived. Spawning unsupervised processes is only fine if
> you spawn the process to do exactly one thing and that thing cannot get the
> process stuck (otherwise you got an invisible leak). And you say it
> yourself, your processes do keep-alive. So they can be open for quite a
> while.
>
> Now if a request handler gets stuck for one reason or another, and the
> process is supervised, it takes about 5 minutes to find what's wrong
> because the OTP tools and libraries do all the work for you in figuring it
> out. You don't have to think, you already know how to deal with issues.
>
> If the process isn't supervised, you cut yourself from most of the
> documented tools and techniques, for example none of your processes will
> show up in observer. You also force your users to figure out the
> alternative ways to debug things instead of what they use everywhere else
> (see Fred's posts [1] and [2]). You have to write custom code to extract
> metrics, logging will work in unexpected ways, etc. And the worse part is
> that you essentially reimplemented a supervisor in your Elli server process.
>
> Yesterday I was debugging an issue and found out file:consult/1 calls were
> getting stuck (bug report incoming, still testing things). If I was using
> Elli, I would have cursed your name many times because of all the time I'd
> have lost trying to understand how to debug this thing.
>
> Following OTP principles is one of Cowboy's most important feature, and
> this will soon be improved again by making even request processes special
> processes that you can debug like you would a gen_server. At this point
> everything will be a special process. This is especially important since
> the Web continues moving toward long-running connections with Websocket,
> SPDY and HTTP/2.0.
>
> [1] http://ferd.ca/poll-results-**erlang-maintenance.html<http://ferd.ca/poll-results-erlang-maintenance.html>
> [2] http://ferd.ca/code-janitor-**nobody-s-dream-everyone-s-job-**
> and-how-erlang-can-help.html<http://ferd.ca/code-janitor-nobody-s-dream-everyone-s-job-and-how-erlang-can-help.html>
>
>
> On 06/26/2013 11:23 AM, Knut Nesheim wrote:
>
>> I'm a bit curious to your comments about unsupervised processes in Elli
>> and Elli not following the OTP principles. Why do you think unsupervised
>> request processes is a bad thing? They are short-lived and you cannot
>> restart them in any meaningful way.
>>
>> It is true that Elli does not hook any of the processes it creates into
>> a supervisor. As a user of Elli, you include the Elli "server" inside
>> your supervision tree. This server starts linked acceptor processes
>> which accepts a new connection, then handles the request (and
>> keep-alive) before they die and the Elli server starts a new acceptor.
>> If any of these processes exits abnormally, Elli knows about it. If you
>> wish to find these processes to debug something, you can use
>> elli:get_acceptors(ElliPid) or process_info(ElliPid, links). Mochiweb
>> and Yaws does more or less the same.
>>
>> Knut
>>
>>
>> On Tue, Jun 25, 2013 at 10:06 PM, Loïc Hoguin <
>> <mailto:>> wrote:
>>
>>     You'd also end up with tons of unsupervised processes, which isn't a
>>     good thing when you want to see what's wrong in your production
>>     system later on (something I last did today and do quite regularly
>>     when consulting). That's the biggest difference between the two,
>>     Cowboy follows OTP principles, elli doesn't. Unfortunately
>>     supervision does have a cost when you need to accept many
>>     short-lived processes quickly, but we have done a lot of work in
>>     Ranch to reduce that cost as much as possible. You could always
>>     replace Ranch with something that doesn't supervise if you really
>>     need to optimize to death, but so far even the handful of companies
>>     that I know that use it for ad bidding and other high frequency
>>     purposes haven't had the need to do that.
>>
>>     In short: removing supervision only looks good on benchmarks.
>>
>>
>>     On 06/25/2013 09:52 PM, okeuday wrote:
>>
>>         When I use their benchmark here:
>>         https://github.com/yesodweb/__**benchmarks<https://github.com/yesodweb/__benchmarks>
>>
>>         <https://github.com/yesodweb/**benchmarks<https://github.com/yesodweb/benchmarks>
>> >
>>         (as mentioned here:
>>         http://www.yesodweb.com/blog/_**_2011/03/preliminary-warp-__**
>> cross-language-benchmarks<http://www.yesodweb.com/blog/__2011/03/preliminary-warp-__cross-language-benchmarks>
>>         <http://www.yesodweb.com/blog/**2011/03/preliminary-warp-**
>> cross-language-benchmarks<http://www.yesodweb.com/blog/2011/03/preliminary-warp-cross-language-benchmarks>
>> >)
>>
>>         to test elli, here:
>>         https://github.com/knutin/elli
>>
>>         I get 99000 req/s.  The (httperf) test of CloudI's http_req erlang
>>         service using cowboy gives 13358 req/s.  cowboy has more
>>         features, so
>>         that can explain the extra average latency which limits
>> throughput.
>>
>>         If you want to understand why their benchmark isn't decent, read
>>         this:
>>         http://www.mnot.net/blog/2011/**__05/18/http_benchmark_rules<http://www.mnot.net/blog/2011/__05/18/http_benchmark_rules>
>>
>>         <http://www.mnot.net/blog/**2011/05/18/http_benchmark_**rules<http://www.mnot.net/blog/2011/05/18/http_benchmark_rules>
>> >
>>
>>         So, if you want something faster in Erlang, you could use ellis,
>>         however, keep in mind their testing isn't long enough to be
>>         meaningful
>>         (due to garbage collection and other impacts on performance).
>>
>>
>>         On Tuesday, June 25, 2013 10:38:25 AM UTC-7, BM Kim wrote:
>>
>>              Damian Dobroczyński <qoocku <at> gmail.com
>>         <http://gmail.com> <http://gmail.com>> writes:
>>
>>               >
>>               > W dniu 25.06.2013 13 <tel:25.06.2013%2013>:51, BM Kim
>> pisze:
>>
>>               > > Hi folks,
>>               > >
>>               > > First of all, I want to apologise for my poor english
>>         skills,
>>               > > since english is not my first language, but I'll try
>>         my best
>>               > > to formulate my quesions as clear as possible.
>>               > >
>>               > > Second, I've just begun to learn erlang, so if I'm
>> asking
>>               > > obvious "noob" questions I apologise for that too in
>>         advance...
>>               > >
>>               > > Anywho, now to my actual question:
>>               > >
>>               > > I am planning to write a high-performance server
>>         application in
>>              erlang,
>>               > > which will primarily handle HTTP requests. After some
>>         reseach with
>>              google,
>>               > > I narrowed down my choices to cowboy, misultin and
>>         mochiweb and
>>              decided
>>               > > to go with the cowboy library first...
>>               > >
>>               > > Looking at some tutorials, I've quickly built a small
>>         server
>>              capable of
>>               > > serving static files and was eager to see first
>>              benchmark-results...
>>               > > I've also built a small Haskell server using Warp
>>         library to
>>              compare it
>>               > > with erlang's cowboy...
>>               > >
>>               > > But my first impression was, that my cowboy server is
>>         much much
>>              slower
>>              than
>>               > > expected when serving static-files and after some
>>         research I
>>              found a
>>              presentation
>>               > > of the cowboy's author claiming that cowboy shouldn't
>>         be used for
>>              serving
>>               > > static-files. So I modified the server code, so that
>>         it replies
>>              to every
>>               > > request with in-memory 4Kb binary blob and compared it
>>         with my
>>              haskell
>>              warp
>>               > > server serving 4kb static file...
>>               > >
>>               > > this is my simple cowboy's http handler:
>>               > >
>>               > >
>>
>>         ------------------------------**__----------------------------**
>> --__----------
>>
>>               > >
>>               > > blob() ->
>>               > >     [<<0:8>> || _ <- lists:seq(1,4096)].
>>               >
>>               > First, try to replace blob/0 function with this:
>>               >
>>               >   blob() -> <<0:(4096*8)>>.
>>               >
>>               > Then, restart the test and report ;)
>>               >
>>
>>
>>              Hi,
>>
>>              Thank you very much for pointing out the obvious mistake...
>>              After correcting it, I got improvement from 5940 req/s to
>>         8650 req/s...
>>
>>              But still much slower than the haskell warp-server, which
>>         has throughput
>>              of 38000 req/s...
>>
>>              But I have another question regarding blob/0. Is it going to
>> be
>>              evaluated
>>              only once (like GHC would do) since it is a pure
>>         expression? I'm not
>>              so sure, since erlang is not pure and any function can have
>>         side-effects
>>              which you can't mark as with the IO monad in Haskell...
>>
>>              ______________________________**___________________
>>              erlang-questions mailing list
>>          <mailto:**>
>> <javascript:>
>>         http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>         <http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>> >
>>              <http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>         <http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>> >>
>>
>>
>>
>>
>>         ______________________________**___________________
>>         erlang-questions mailing list
>>          <mailto:erlang-questions@**erlang.org<>
>> >
>>         http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>
>>         <http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>> >
>>
>>
>>
>>     --
>>     Loïc Hoguin
>>     Erlang Cowboy
>>     Nine Nines
>>     http://ninenines.eu
>>     ______________________________**___________________
>>     erlang-questions mailing list
>>      <mailto:erlang-questions@**erlang.org<>
>> >
>>     http://erlang.org/mailman/__**listinfo/erlang-questions<http://erlang.org/mailman/__listinfo/erlang-questions>
>>     <http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>> >
>>
>>
>>
>
> --
> Loïc Hoguin
> Erlang Cowboy
> Nine Nines
> http://ninenines.eu
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130627/68c2f2d8/attachment.html>


More information about the erlang-questions mailing list