<div class="gmail_quote">Hi Mike,<br><br>On Mon, Apr 18, 2011 at 12:00 PM, Mike Meyer <span dir="ltr"><<a href="mailto:mwm@mired.org">mwm@mired.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
> It's useful to use non-determinism (i.e. concurrency) to model a server<br><div class="im">
> processing multiple requests. Since requests are independent and shouldn't<br>
> impact each other we'd like to model them as such. This implies some level<br>
> of concurrency (whether using threads and processes).<br>
<br>
</div>But because the requests are independent, you don't need concurrency<br>
in this case - parallelism is sufficient. The unix process model works<br>
quite well. Compared to a threaded model, this is more robust (if a<br>
process breaks, you can kill and restart it without affecting other<br>
processes, whereas if a thread breaks, restarting the process and all<br>
the threads in it is the only safe option) and scalable (you're<br>
already doing ipc, so moving processes onto more systems is easy, and<br>
trivial if you design for it). The events handled by a single process<br>
are simple enough that your callback/event spaghetti can line up in<br>
nice, straight strands.<br></blockquote><div><br>Threads and processes are both concurrent programming models. You get parallelism if you map the threads/processes to more than one CPU core.<br><br>Processes (and to some extents threads) only scale (well) horizontally; given more processes you can handle more concurrent requests. However, they don't scale vertically, given more processes you don't handle a particular request any faster*. Since GHC's scheduler deals with both CPU bound threads and I/O bound threads you can use it to process single requests faster. A typically CPU bound activity is page rendering, which you could break up like this:<br>
<br>renderPage = firstPart `par` secondPart `pseq` combine firstPart secondPart<br> where<br> firstPart = render ...<br> secondPart = render ...<br></div><div><br>This would run in GHC's per CPU core thread pool, if there are free CPU resources to do so.<br>
<br>Regarding robustness I think Simon covered most of that. GHC's RTS gives you the building blocks you need to write Erland style process monitoring/restart.<br><br>* In theory you could use IPC to implement parallel algorithms using processes, but it's hard to achieve real world performance gains this way as the overhead is quite large.<br>
<br>Johan<br><br></div></div>