[racket] Web server

From: Brian Adkins (racketusers at lojic.com)
Date: Thu Jul 17 10:49:01 EDT 2014

[forgot *again* to reply-all and only sent this to Jay initially - resending to group]

Thanks for the response Jay.

I may have glossed over the parallelism & concurrency aspects a bit too much when I first read those sections in the Racket Guide. I now see in 20.1 re: Futures:

"The level of parallelism available from those constructs, however, is limited by several factors, and the current implementation is best suited to numerical tasks."

and in 20.2:

"The place form creates a place, which is effectively a new Racket instance that can run in parallel to other places, including the initial place."

"Places" appears to be similar to my current approach of having multiple Ruby/Rails processes handle web requests. In the case of Ruby/Rails, it's a very inefficient use of memory, i.e. the amount of RAM needed to fully utilize all cores is *much* higher than it should be when spinning up multiple app server processes that each load the entire Rails framework. Each Rails process is essentially single-threaded.

I was hoping to gain a big improvement of Ruby/Rails with Racket, and that may be possible even with the current implementation (both Ruby & Rails are performance-challenged), but can you give me some idea of the level importance multi-core performance is in the Racket community moving forward? I'm taking a fairly long term perspective with Racket, so the "roadmap" is as important to me as the current implementation.

I'm referring to Racket in general, not just the web server.

I haven't done much research or testing yet, so maybe a combination of Places and Threads will be sufficient for my needs. Maybe one Place per CPU core w/ multiple threads to keep the CPU busy while some threads are blocked on I/O requests.

Thanks,
Brian

On Jul 16, 2014, at 10:17 PM, Jay McCarthy wrote:

> It wouldn't have a big impact on the server. The big question is how
> to effectively use multi-core in Racket programs generally.
> 
> Futures are really only good for numerical codes that stay in the JIT,
> which doesn't sound like most Web programs. That said, it is trivial
> to implement:
> 
> #lang racket/base
> (require racket/future
>        web-server/servlet-env
>        web-server/http)
> 
> (define (fib n)
> (if (< n 2)
>   1
>   (+ (fib (- n 1))
>      (fib (- n 2)))))
> 
> (define (start req)
> (touch
>  (future
>   (λ ()
>     (response/xexpr
>      `(html
>        (body
>         (p "It's "
>            ,(number->string
>              (fib (random 20)))))))))))
> 
> (serve/servlet start)
> 
> Boom! That's a servlet that uses multi-core to handle every request...
> of course, it probably doesn't pay in this or most other programs.
> 
> Places are for more coarse-grained things and you can pass file
> descriptors, so it's feasible to have a TCP accepter that feeds work
> to a group of places servicing the requests. However, places must not
> use mutation to communicate higher-order values (they can communicate
> flat values like numbers with mutation), so they couldn't share
> continuations. It would be trivial to use serializable continuations
> or to implement a continuation manager that stored all the
> continuations in a single place. Session affinity doesn't really make
> a lot of sense in the continuation context, fwiw.
> 
> My guess is that you could spend less than 100 lines to implement the
> continuation manager and the place-based worker setup. (This is based
> on the normal server setup just being 127 lines and the manager
> interface being implemented in as little as 40 lines.) This might be
> worth it.
> 
> Jay
> 
> 
> On Wed, Jul 16, 2014 at 4:09 PM, Brian Adkins <racketusers at lojic.com> wrote:
>> I haven't looked into the Racket web server much yet, so I'd like to understand the implications of this.
>> 
>> My experience is with stateless http app servers (primarily with Unicorn Ruby servers at the moment), so firing up a number of worker processes and having something like nginx proxy to them works well to fully utilize all cores.
>> 
>> I think I read that the Racket web server makes use of continuations, so I expect some sort of process affinity would be necessary, where a given user's requests are always proxied to the same worker process - is that right? Is it common to use multiple web server processes in Racket web apps?
>> 
>> In your estimation, what is the feasibility of adding multi-core support to the Racket web server? For example, is it reasonably feasible and on the current roadmap, or would it require massive changes to the web server?
>> 
>> Thanks,
>> Brian
>> 
>> On Jul 16, 2014, at 8:42 AM, Jay McCarthy wrote:
>> 
>>> It does not use multiple cores if they are available.
>>> 
>>> Jay
>>> 
>>> On Wed, Jul 16, 2014 at 7:02 AM, Sean Kemplay <sean.kemplay at gmail.com> wrote:
>>>> Hello,
>>>> 
>>>> I am interested in the racket web server for some micro services. Just
>>>> wondering if by default it runs across multiple cores or if it is restricted
>>>> to one due to threads in racket.
>>>> 
>>>> Regards,
>>>> Sean
>>>> 
>>>> 
>>>> ____________________
>>>> Racket Users list:
>>>> http://lists.racket-lang.org/users
>>>> 
>>> 
>>> 
>>> 
>>> --
>>> Jay McCarthy
>>> http://jeapostrophe.github.io
>>> 
>>>         "Wherefore, be not weary in well-doing,
>>>    for ye are laying the foundation of a great work.
>>> And out of small things proceedeth that which is great."
>>>                        - D&C 64:33
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/users
>> 
> 
> 
> 
> -- 
> Jay McCarthy
> http://jeapostrophe.github.io
> 
>          "Wherefore, be not weary in well-doing,
>     for ye are laying the foundation of a great work.
> And out of small things proceedeth that which is great."
>                         - D&C 64:33



Posted on the users mailing list.