<div class="gmail_quote">Hi Mike,<br><br>On Mon, Apr 18, 2011 at 12:00 PM, Mike Meyer <span dir="ltr">&lt;<a href="mailto:mwm@mired.org">mwm@mired.org</a>&gt;</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;">

&gt; It&#39;s useful to use non-determinism (i.e. concurrency) to model a server<br><div class="im">
&gt; processing multiple requests. Since requests are independent and shouldn&#39;t<br>
&gt; impact each other we&#39;d like to model them as such. This implies some level<br>
&gt; of concurrency (whether using threads and processes).<br>
<br>
</div>But because the requests are independent, you don&#39;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&#39;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&#39;t scale vertically, given more processes you don&#39;t handle a particular request any faster*. Since GHC&#39;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&#39;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&#39;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&#39;s hard to achieve real world performance gains this way as the overhead is quite large.<br>

<br>Johan<br><br></div></div>