libevent2

Started by Jeff, January 04, 2013, 12:01:31 PM

Previous topic - Next topic

Jeff

Howdy folks. Haven't been around in a while. Wanted to let you know that I put together a wrapper for libevent2 using the new FFI features. Made it very easy. You can find it on github here - https://github.com/jsober/nl-event">https://github.com/jsober/nl-event.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

cormullion

#1
Hi Jeff. It has indeed been a while - glad to see you've not forgotten anything!

Lutz

#2
The libevent2 module is also available here:



http://www.newlisp.org/modules/various/libevent2.lsp.html">http://www.newlisp.org/modules/various/ ... 2.lsp.html">http://www.newlisp.org/modules/various/libevent2.lsp.html



... and I added a location link back to github

jopython

#3
I wonder what this means for newLisp?

Does this mean we don't have to spawn a separate newlisp process for each http request  because we have events?

Lutz

#4
No different processes are required, newLISP could execute another function while waiting for the callback. The callback will interrupt current processing and execute the callback function. After the callback function finished, the interrupted one will continue.

Jeff

#5
Actually, that is not exactly true. That is more how signals work, although not in libevent. In libevent, the application is controlled by the loop. Before starting the loop, you register at least one socket or timer to run in it. It is an error to run a loop with no events registered.



For example, to implement a server, you would register the listening socket. When a remote client connects, your registered callback is triggered. You accept the new connection, creating a new socket, and register an event handler for that socket as well. When it sends a request, your handler is triggered with a read event. Your app determines its response, which it sends on the next write event.



At no point does execution yield. If your server takes a long time to build a response to a request, the entire application will block. This is where multiple processes might be used, allowing the server process to continue to service clients while child processes do the work of interpreting requests and generating responses.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Jeff

#6
Here is an example of how a simple echo server might look:


(load "libevent2.lsp")

(setf listen (net-listen 8000))

(unless listen
  (throw-error (net-error)))

(libevent:init)
(libevent:watch listen libevent:READ
  (lambda (fd e id , client)
    ; accept a new connection
    (setf client (net-accept listen))

    ; watch for requests
    (libevent:watch client libevent:READ
      (lambda (fd e id , req)
        ; read request
        (setf req (read-line fd))

        ; On a real server, here is where you would process the request,
        ; most likely in a secondary process. In that case, you would execute
        ; the code below when it finished, rather than immediately after
        ; the request comes in.

        ; wait for client to be ready to accept a response
        (libevent:watch-once client libevent:WRITE
          (lambda (fd e id)
            ; send response
            (write fd req)))))))

(libevent:run)


A real server would have to watch for timeouts, disconnects, etc., as well, but this gives you the basic idea.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code