Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Gerd Stolpmann <info@gerd-stolpmann.de>
To: Gabriel Kerneis <kerneis@enst.fr>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Re: Why OCaml rocks
Date: Fri, 09 May 2008 14:41:12 +0200	[thread overview]
Message-ID: <1210336872.17578.53.camel@flake.lan.gerd-stolpmann.de> (raw)
In-Reply-To: <20080509115809.GA5717@kerneis.info>


Am Freitag, den 09.05.2008, 13:58 +0200 schrieb Gabriel Kerneis:
> On Fri, May 09, 2008 at 01:12:06PM +0200, Gerd Stolpmann wrote:
> > Of course, we did not use multithreading very much. We are relying on
> > multi-processing (both "fork"ed style and separately started programs),
> > and multiplexing (i.e. application-driven micro-threading). I especially
> > like the latter: Doing multiplexing in O'Caml is fun, and a substitute
> > for most applications of multithreading. For example, you want to query
> > multiple remote servers in parallel: Very easy with multiplexing,
> > whereas the multithreaded counterpart would quickly run into scalability
> > problems (threads are heavy-weight, and need a lot of resources).
> 
> Do you have any pointer on multiplexing (or some piece of code you could
> show)? This seems interesting but I can't figure out what it looks like.

For some background information look here:

- Asynchronous RPC:
  http://projects.camlcity.org/projects/dl/ocamlnet-2.2.9/doc/html-main/Rpc_intro.html

  Look for the asynchronous examples

- The low-level side is enlightened here:
  http://projects.camlcity.org/projects/dl/ocamlnet-2.2.9/doc/html-main/Equeue_intro.html

Here is a code snipped from our production code. It is from a server
that continuously monitors RPC ports:

let check_port esys p =
  (* Checks the port p continuously until mon_until - then the port is deleted
     from the list
   *)
  let (ba,ua) = Lazy.force shmem in
  let rec next_check() =
    let now = Unix.gettimeofday() in
    if now < Int64.to_float p.mon_until then (
      let conn =
        match p.mon_port with
          | `local_port _ ->
              failwith "Monitoring local ports is not supported"
          | `inet4_port a ->
              Rpc_client.Inet(a.inet4_host, a.inet4_port) in
      let rpc_proto =
        match p.mon_protocol with
          | `tcp -> Rpc.Tcp
          | `udp -> Rpc.Udp in
      let client = 
        Capi_clnt.Generic.V1.create_client2
          ~esys
          (`Socket(rpc_proto, conn, Rpc_client.default_socket_config)) in
      Rpc_helpers.set_exn_handler "generic" client;
      Rpc_client.configure client 0 5.0;  (* 5 secs timeout *)
      Capi_clnt.Generic.V1.ping'async
        client
        ()
        (fun get_reply ->
           (* We are called back when the "ping" is replied or times out *)
           let successful = try get_reply(); true with _ -> false in
           Rpc_client.shut_down client;
           p.mon_alive <- successful;
           ba.{ p.mon_shmpos } <- (if successful then 1L else 0L);
           let g = Unixqueue.new_group esys in
           Unixqueue.once esys g 1.0 next_check
        );
    )
    else
      remove_port p
  in
  next_check()

This (single-process) server can watch a high number of ports at the
same time and consumes almost no resources. Note how the loop is
programmed, essentially we have

let rec next_check() =
   ...
   Capi_clnt.Generic.V1.ping'async
     client
     ()
     (fun get_reply ->
        ...
        Unixqueue.once esys g 1.0 next_check
     )

("once" calls the passed functions once in the future, here after 1
second). Basically, you have a closure with the action in the event
queue, and when the action is done, a new closure is appended to this
queue to schedule the next task. Using closures is important because
this enforces that all stack values are copied to the heap (I view
closures in this context as a means to "heapify" values), so the
recursion is stackless.

This server is also interesting because we actually use shared memory
for speeding up the communication path between client and server (look
at the "ba.{ p.mon_shmpos } <- ..." line). The client is here the
program that wants to know whether a port is alive. This is an
optimization for the most frequent case, but works only if client and
server reside on the same node. (Actually, we run this server on every
node, so this is always the case.) Effectively, it is no big problem to
combine shared memory style and multi-processing.

Gerd
-- 
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany 
gerd@gerd-stolpmann.de          http://www.gerd-stolpmann.de
Phone: +49-6151-153855                  Fax: +49-6151-997714
------------------------------------------------------------



  parent reply	other threads:[~2008-05-09 12:40 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-09  0:39 Why OCaml sucks Jon Harrop
2008-05-09  1:11 ` [Caml-list] " Matthew William Cox
2008-05-09  5:10   ` [Caml-list] Re: Why OCaml **cks Jon Harrop
2008-05-09  4:45 ` [Caml-list] Re: Why OCaml sucks Arthur Chan
2008-05-09  5:09   ` Jon Harrop
2008-05-09 11:12     ` [Caml-list] Re: Why OCaml rocks Gerd Stolpmann
2008-05-09 11:58       ` Gabriel Kerneis
2008-05-09 12:10         ` Concurrency [was Re: [Caml-list] Re: Why OCaml rocks] Robert Fischer
2008-05-09 12:41         ` Gerd Stolpmann [this message]
2008-05-09 12:49         ` [Caml-list] Re: Why OCaml rocks David Teller
2008-05-09 18:10       ` Jon Harrop
2008-05-09 20:40         ` Gerd Stolpmann
2008-05-09 20:55           ` Berke Durak
2008-05-10 10:56             ` Gerd Stolpmann
2008-05-09 21:00           ` Till Varoquaux
2008-05-09 21:13             ` Berke Durak
2008-05-09 22:26               ` Richard Jones
2008-05-09 23:01                 ` Berke Durak
2008-05-10  7:52                   ` Richard Jones
2008-05-10  8:24                     ` Berke Durak
2008-05-10  8:51                       ` Richard Jones
2008-05-13  3:47           ` Jon Harrop
2008-05-09 22:25         ` David Teller
2008-05-09 22:57           ` Vincent Hanquez
2008-05-10 19:59           ` Jon Harrop
2008-05-10 21:39             ` Charles Forsyth
2008-05-11  3:58               ` Jon Harrop
2008-05-11  9:41                 ` Charles Forsyth
2008-05-12 13:22             ` Richard Jones
2008-05-12 18:07               ` Jon Harrop
2008-05-12 20:05                 ` Arthur Chan
2008-05-13  0:42               ` Gerd Stolpmann
2008-05-13  1:19                 ` Jon Harrop
2008-05-13  2:03                   ` Gerd Stolpmann
2008-05-13  3:13                     ` Jon Harrop
2008-05-12 20:33             ` Arthur Chan
2008-05-12 21:22               ` Till Varoquaux
2008-05-09 13:00     ` [Caml-list] Re: Why OCaml sucks Ulf Wiger (TN/EAB)
2008-05-09 17:46       ` Jon Harrop
2008-05-09 18:17         ` Ulf Wiger (TN/EAB)
2008-05-10  1:29           ` Jon Harrop
2008-05-10 14:51             ` [Caml-list] Re: Why OCaml **cks Ulf Wiger (TN/EAB)
2008-05-10 18:19               ` Jon Harrop
2008-05-10 21:58                 ` Ulf Wiger (TN/EAB)
2008-05-10 18:39               ` Mike Lin
2008-05-12 13:31           ` [Caml-list] Re: Why OCaml sucks Kuba Ober
2008-05-12 18:18             ` Jon Harrop
2008-05-12 13:13   ` Kuba Ober
2008-05-12 19:32     ` Arthur Chan
2008-05-09  6:31 ` Tom Primožič
2008-05-09  6:46 ` Elliott Oti
2008-05-09  7:53   ` Till Varoquaux
2008-05-09  7:45 ` Richard Jones
2008-05-09  8:10   ` Jon Harrop
2008-05-09  9:31     ` Richard Jones
2008-05-09  7:58 ` [Caml-list] Re: Why OCaml rocks David Teller
2008-05-09 10:29   ` Jon Harrop
2008-05-09 13:08     ` David Teller
2008-05-09 15:38     ` Jeff Polakow
2008-05-09 18:09       ` Jon Harrop
2008-05-09 20:36         ` Berke Durak
2008-05-09 22:34         ` Richard Jones
2008-05-14 13:44           ` Kuba Ober
2008-05-09  8:29 ` constructive criticism about Ocaml Ulf Wiger (TN/EAB)
2008-05-09  9:45 ` [Caml-list] Re: Why OCaml sucks Vincent Hanquez
2008-05-09 10:23   ` [Caml-list] Re: Why OCaml **cks Jon Harrop
2008-05-09 22:01     ` Vincent Hanquez
2008-05-09 22:23       ` David Teller
2008-05-10  8:36       ` Christophe TROESTLER
2008-05-10  9:18         ` Vincent Hanquez
2008-05-09 11:37   ` [Caml-list] Re: Why OCaml sucks Ralph Douglass
2008-05-09 13:02     ` [Caml-list] Re: Why OCaml rocks David Teller
2008-05-09 12:33 ` not all functional languages lack parallelism Ulf Wiger (TN/EAB)
2008-05-09 18:10   ` Jon Harrop
2008-05-09 20:26     ` Ulf Wiger (TN/EAB)
2008-05-12 12:54 ` [Caml-list] Re: Why OCaml sucks Kuba Ober
2008-05-12 14:16   ` Jon Harrop
2008-05-13 13:33     ` Kuba Ober
2008-05-13 13:49       ` Robert Fischer
2008-05-13 14:01         ` Brian Hurt
2008-05-13 14:13           ` Robert Fischer
2008-05-13 15:18             ` Berke Durak
2008-05-14  4:40             ` Kuba Ober
2008-05-13 14:25           ` Gerd Stolpmann
2008-05-14  4:29           ` Kuba Ober
2008-05-12 13:01 ` Kuba Ober
2008-05-12 19:18   ` Arthur Chan
2008-05-12 19:41     ` Karl Zilles
2008-05-13 13:17     ` Kuba Ober

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1210336872.17578.53.camel@flake.lan.gerd-stolpmann.de \
    --to=info@gerd-stolpmann.de \
    --cc=caml-list@yquem.inria.fr \
    --cc=kerneis@enst.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox