- CMUCL/SBCL's SERVE-EVENT
- IOlib
- cl-event (libevent for Lisp, using cffi; three years old)
- cl-async (also using cffi libevent wrapper, actively developed)
I was ready to dive in and get things current, when one last Google search turned up cl-async. This little bugger was hard to find, as at that point it had not been listed on CLiki. (But it is now :-)). Andrew Lyon has done a tremendous amount of work on cl-async, with a very complete set of bindings for libevent. This is just what I had been looking for, so I jumped in immediately.
As one might imagine from the topic of this post, there's a lot to be explored, uncovered, and developed further around async programming in Lisp. I'll start off slowly with a small example, and add more over the course of time.
I also hope to cover IOlib and SBCL's SERVE-EVENT in some future posts. Time will tell... For now, let's get started with cl-async in SBCL :-)
Dependencies
In a previous post, I discussed getting an environment set up with SBCL, I the rest of this post assumes that has been read and done :-)
Getting cl-async and Setting Up an SBCL Environment for Hacking
Now let's download cl-async and install the Libevent bindings :-)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ git clone https://github.com/orthecreedence/cl-async.git | |
$ cd cl-async | |
$ tar cvzf libevent2.tgz ./libevent2 | |
$ start-sbcl | |
* (require 'asdf-install) | |
("ASDF-INSTALL") | |
* (asdf-install:install "libevent2.tgz") | |
Install where? | |
1) System-wide install: | |
System in /usr/lib/sbcl/site-systems/ | |
Files in /usr/lib/sbcl/site/ | |
2) Personal installation: | |
System in /home/oubiwann/.sbcl/systems/ | |
Files in /home/oubiwann/.sbcl/site/ | |
--> 2 |
With the Lisp Libevent bindings installed, we're now ready to create a Lisp image to assist us when exploring cl-async. A Lisp image saves the current state of the REPL, with all the loaded libaries, etc., allowing for rapid start-ups and script executions. Just the thing, when you're iterating on something :-)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ start-sbcl | |
* (ql:quickload "cl-async") | |
[snip: lots of output for downloading and installing dependencies] | |
* (sb-ext:save-lisp-and-die "cl-async.core") |
Example: Adding a Signal Handler
Let's dive into some signal handling now! Here is some code I put together as part of an effort to beef up the examples in cl-async:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ql:quickload "cl-async") | |
;; define a callback for our signal | |
(defun sigint-cb (signal-received) | |
(format t "You interrupted me!~%") | |
(format t "I got signal `~a`~%" signal-received) | |
(as:exit-event-loop)) | |
;; set up a signal handler | |
(defun setup-handler () | |
(as:signal-handler as:+sigint+ #'sigint-cb)) | |
;; start the event loop | |
(as:start-event-loop #'setup-handler) |
Note that the as: is a nickname for the package namespace cl-async:.
As one might expect, there is a function to start the event loop. However, what is a little different is that one doesn't initialize the event loop directly, but with a callback. As such, one cannot set up handlers, etc., except within the scope of this callback.
We've got the setup-handler function for that, which adds a callback for a SIGINT event. Let's try it out :-)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ sbcl --core cl-async.core --script 03-handle-signal.lisp | |
To load "cl-async": | |
Load 1 ASDF system: | |
cl-async | |
; Loading "cl-async" |
When we send a SIGINT with ^C, we can watch our callback get fired:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
^CYou interrupted me! | |
I got signal `2` |
Next up, we'll take a look at other types of handlers in cl-async.
1 comment:
I'm loving these common lisp posts, please keep them coming! I've just started learning cl this year and things like thus are really helpful. Cheers
Post a Comment