RSS Feed

Lisp Project of the Day

cl-events

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

Or see the list of project sponsors.

cl-eventseventsthreads

Documentation😀
Docstrings🥺
Tests 😀
Examples😀
RepositoryActivity🥺
CI 😀

This is the library by @dead_trickster. It implements a pub-sub API and allows to:

  • create an event object;
  • subscribe on it;
  • fire the event.

CL-Events provides a way to add a hook point for your application.

Here is the simplest example. Here we create a single-threaded event where all callbacks will be called sequentially:

POFTHEDAY> (defparameter *on-click*
             (make-instance 'cl-events:event))

POFTHEDAY> (defun the-callback (message)
             ;; pretend, we need some time to process the callback
             (sleep 1)
             (format t "MSG [~A]: ~A~%"
                     (bt:current-thread)
                     message))

POFTHEDAY> (cl-events:event+ *on-click*
                             'the-callback)

POFTHEDAY> (cl-events:event! *on-click*
                             "Button clicked!")
MSG [#<THREAD "sly-channel-1-mrepl-remote-1" RUNNING {1003955B33}>]: Button clicked!
NIL

To make them execute in parallel, you only need to replace the type of the event object. Pay attention to the thread's name in the callback's output. They are different:

POFTHEDAY> (defparameter *on-click*
             (make-instance 'cl-events:broadcast-event))

POFTHEDAY> (defun the-callback (handler-name message)
             ;; pretend, we need some time to process the callback
             (sleep 1)
             (format t "MSG [~A/~A]: ~A~%"
                     handler-name
                     (bt:current-thread)
                     message))

POFTHEDAY> (cl-events:event+ *on-click*
                             (alexandria:curry 'the-callback
                                               "First handler"))

POFTHEDAY> (cl-events:event+ *on-click*
                             (alexandria:curry 'the-callback
                                               "Second handler"))

POFTHEDAY> (cl-events:event! *on-click*
                             "Button clicked!")
NIL
MSG [Second handler/#<THREAD "lparallel" RUNNING {1005A97983}>]: Button clicked!
MSG [First handler/#<THREAD "lparallel" RUNNING {1005A96F93}>]: Button clicked!

Also, in this case, event! function returns before all handlers are called.

In this case, parallel execution is implemented using lparallel's thread pool. There are more executors available and you can implement your own.


Brought to you by 40Ants under Creative Commons License