unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [ann] fibers 0.1.0
@ 2016-07-04  8:34 Andy Wingo
  2016-07-06 17:29 ` Amirouche Boubekki
  0 siblings, 1 reply; 3+ messages in thread
From: Andy Wingo @ 2016-07-04  8:34 UTC (permalink / raw)
  To: guile-user; +Cc: guile-devel

Hi all,

I just released Fibers 0.1.0.  Fibers is an experimental facility for
Erlang-like concurrency in Guile 2.2.

As an example, here is a ping server written in Fibers:

    (define (socket-loop socket store)
      (let loop ()
        (match (accept socket)
          ((client . addr)
           (set-nonblocking! client)
           ;; Disable Nagle's algorithm.  We buffer ourselves.
           (setsockopt client IPPROTO_TCP TCP_NODELAY 0)
           (spawn (lambda () (client-loop client addr store)))
           (loop)))))

As you can see it's straightforward in style.  For each client that
comes in, we spawn a fiber to handle the client.  Here's the fiber that
handles the client:

    (define (client-loop port addr store)
      (let loop ()
        (let ((line (read-line port)))
          (cond
           ((eof-object? line)
            (close-port port))
           (else
            (put-string port line)
            (put-char port #\newline)
            (force-output port)
            (loop))))))

Nice, no?  Whenever read-line, put-string, put-char, or force-output
would block, a fiber suspends the the current scheduler, adds its fd to
an epoll set, and the scheduler runs something else.  There's a bit of
boilerplate in the example when setting up the socket to make things
nonblocking, but anyway here's the whole thing:

  https://github.com/wingo/fibers/blob/master/examples/ping-server.scm

Fibers is in early stages.  It used to be called "ethreads" and lived in
an experimental branch of Guile, but now that we have added the
suspendable ports facility to Guile, Fibers can live in an external
repo.

I want Guile to have a good concurrency story around servers and
clients, where there can be thousands of connections at once and no
blocking.  I think it can be part of Guile eventually but we need to
experiment as a community.  Fibers is in the same space as guile-a-sync
or 8sync, which have already been doing great experimentation in this
regard.  I suspect that in the end we will bless one facility as the
default one and incorporate it into Guile, but even then we will still
provide the ability for the user to choose a different set of
concurrency primitives.

The to-do list is somewhat long.

 * Fibers doesn't have any concurrency primitives besides sleep and what
   suspendable-ports provides.  I think the next step is to implement
   channels, like Go.

 * Missing tests :/ Though there is a memcached implementation in the
   examples, and a web server implementation that uses fibers.

 * Nice REPL facilities, like ,fibers to list all fibers and their
   states, ,fiber to enter a backtrace using a fiber's delimited
   continuation as the state, ,fkill to kill a fiber, and so on.

 * Documentation.

 * Performance improvements, testing, and auditing for correctness and
   fairness.

Currently a fiber-based ping client that opens 4000 concurrent
connections and makes 25 pings each takes around a second or two on my
machine, so let's say 50K pings per second per core.  The web server
currently runs at around 10K requests/second/core for a simple "hello
world" page.  I'm sure there are improvements that can be made but these
numbers are already OK.

Download fibers from here:

  https://wingolog.org/pub/fibers/fibers-0.1.0.tar.gz

The sha256sum is:

  6b7654d27781af2602b9e692f1d2a932a582c68e0a14efa38eaba265d4b464ab  fibers-0.1.0.tar.gz

Happy hacking,

Andy



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [ann] fibers 0.1.0
  2016-07-04  8:34 [ann] fibers 0.1.0 Andy Wingo
@ 2016-07-06 17:29 ` Amirouche Boubekki
  2016-07-07 10:07   ` Andy Wingo
  0 siblings, 1 reply; 3+ messages in thread
From: Amirouche Boubekki @ 2016-07-06 17:29 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-user, guile-devel, guile-devel

(Resent the mail to the mailing list)

On 2016-07-04 10:34, Andy Wingo wrote:
> Hi all,
> 
> I just released Fibers 0.1.0.  Fibers is an experimental facility for
> Erlang-like concurrency in Guile 2.2.
> 
> As an example, here is a ping server written in Fibers:
> 
>     (define (socket-loop socket store)
>       (let loop ()
>         (match (accept socket)
>           ((client . addr)
>            (set-nonblocking! client)
>            ;; Disable Nagle's algorithm.  We buffer ourselves.
>            (setsockopt client IPPROTO_TCP TCP_NODELAY 0)
>            (spawn (lambda () (client-loop client addr store)))
>            (loop)))))
> 
> As you can see it's straightforward in style.  For each client that
> comes in, we spawn a fiber to handle the client.  Here's the fiber that
> handles the client:
> 
>     (define (client-loop port addr store)
>       (let loop ()
>         (let ((line (read-line port)))
>           (cond
>            ((eof-object? line)
>             (close-port port))
>            (else
>             (put-string port line)
>             (put-char port #\newline)
>             (force-output port)
>             (loop))))))
> 

It's ok to use several put-* procedure instead of one? For example:

```
(put-string port "abc")
```

is not better than:

```
(put-char port #\a)
(put-char port #\b)
(put-char port #\c)
```

Otherwise said is there still buffering when using non blocking sockets?

Does (web client) http-get work vanilla with fiber?


Thanks for the hard work!



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [ann] fibers 0.1.0
  2016-07-06 17:29 ` Amirouche Boubekki
@ 2016-07-07 10:07   ` Andy Wingo
  0 siblings, 0 replies; 3+ messages in thread
From: Andy Wingo @ 2016-07-07 10:07 UTC (permalink / raw)
  To: Amirouche Boubekki; +Cc: guile-user, guile-devel, guile-devel

On Wed 06 Jul 2016 19:29, Amirouche Boubekki <amirouche@hypermove.net> writes:

> (Resent the mail to the mailing list)

Resending my reply, I didn't notice it was a private message.  (Please
don't send me private messages about Guile; always send to the list.)

On Tue 05 Jul 2016 21:16, Amirouche Boubekki <amirouche@hypermove.net> writes:

> It's ok to use several put-* procedure instead of one? For example:
>
> ```
> (put-string port "abc")
> ```
>
> is not better than
>
> (put-char port #\a)
> (put-char port #\b)
> (put-char port #\c)

put-string is better performance-wise than multiple put-char
invocations.  But you should check :)

> Otherwise said (?) is there still buffering when using non blocking
> sockets?

Guile sockets are unbuffered by default but that can be changed by
calling `setvbuf' on them.

> Does (web client) http-get work vanilla when the fiber is running?

It should work, yes.  The problem would come in only if it uses I/O
primitives that haven't been expressed in terms of the low-level
non-blocking I/O primitives.  That would be a suspendable-ports bug.  In
that case some I/O operations would actually block instead of running
properly asynchronously.  That's the case for example if you do

  (display "foo" port)

Display hasn't been rewritten in Scheme yet, so it uses C internally and
the C ports code won't suspend; it will block.  We need to either change
uses of `display' to use put-string / put-char, or reimplement `display'
in scheme.  The latter is hard but it's possible to incrementally
reimplement `display', where for example `display' on a string will use
put-string, but on anything else dispatches to C.

Andy



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-07-07 10:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-04  8:34 [ann] fibers 0.1.0 Andy Wingo
2016-07-06 17:29 ` Amirouche Boubekki
2016-07-07 10:07   ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).