Events
This section goes over basic events in cl-async and how to use them for various purposes, such as triggering a function after a specific amount of time, or watching an OS file descriptor for changes.
- event class
- event-c accessor
- event-freed-p method
- free-event function
- remove-event function
- add-event function
- delay function
- with-delay macro
- interval function
- with-interval macro
- remove-interval function
- make-event function
- event-freed condition
- ref function
- unref function
event
The event class wraps around a libuv event C object. It is accepted by free-event, remove-event, and add-event.
event-c
Allows you to access the underlying C object associated with this event.
It’s exported in case you need to do something cl-async doesn’t provide.
event-freed-p
Returns t
if an event is already freed (via free-event), and
nil
if it has not been freed. Trying to operate on an event that has been
freed will result in an event-freed error.
free-event
(defun free-event (event))
=> nil
Frees an event’s underlying event object, and performs any needed cleanup. It is absolutely safe to free an event that is pending (watched by the event loop) or active. Doing so makes the event inactive/non-pending before freeing.
remove-event
(defun remove-event (event))
=> t/nil
This removes an event from the event loop. The event still exists, and can be
added back into the event loop via add-event, but must be
activated again after adding back into the loop (by either specifying
:active t
or giving a timeout in seconds via :timeout
.
Returns t
on success, nil
otherwise (a nil
can mean that the event is
already removed and doesn’t need to be remove again).
add-event
(defun add-event (event &key timeout activate)
=> nil
Makes an event pending (adds it to the event loop it was created with). This is mainly done to resume an event that was removed from the event loop using remove-event.
If :timeout
is specified, the event will fire in the given number of seconds
regardless of whether or not the other conditions the event is watching for are
met.
If :activate
is true and :timeout
is null, the event t is instead manually
activated.
Note that if you omit both :activate
and :timeout
, the event will be
added to the loop but not activated (and will never be run unless you call
add-event
again with either :activate
or :timeout
specified).
delay
(defun delay (callback &key time event-cb))
=> event
Run a function asynchronously. Takes two optional parameters: time
, the number
of seconds to wait before running the given function (run with no delay if
nil
), and event-cb
which can be used to catch application errors should they
occur while running callback
.
;; example:
(delay (lambda () (format t "Run me immediately after control is given to the event loop.~%")))
(delay (lambda () (format t "I will run 3.2 seconds after calling (delay).~%")) :time 3.2)
with-delay
(defmacro with-delay ((seconds) &body body))
=> event
Syntax wrapper around delay to make it a bit less annoying to type.
;; example:
(with-delay (5)
(format t "Five seconds passed!~%"))
interval
(defun interval (callback &key time event-cb))
=> cancel-closure
Like delay, but runs the given callback every time
seconds until
stopped by either funcall
ing the returned closure, or calling remove-inteval
on the returned closure.
with-interval
(defmacro with-interval ((seconds) &body body))
=> cancel-closure
Syntax wrapper around interval. Returns the same cancellation
closure that interval
does.
remove-interval
(defun remove-interval (interval-closure))
=> nil
When given the closure returned from calling interval, stops the timer on the interval (cancels it).
make-event
(defun make-event (callback &key event-cb))
=> event
Makes it easy to add an arbitrary event to the event loop. This event needs to
either be activated via (add-event event :activate t)
(see add-event)
or removed manually.
This is a very thin wrapper around delay, in fact all it does is call
delay
with a one-year delay.
event-freed
extends event-error
This error is thrown when an event that has been freed is operated on in some way. You can test if an event is freed already using the event-freed-p method.
ref
(defmethod ref ((handle event)))
=> nil
References the event, making it so that the event loop will not exit until the event is freed.
See unref as well.
unref
(defmethod unref ((handle event)))
=> nil
Unreferences the event. This means that even if it’s active in the event loop, the loop can exit without the event being closed/freed.
See ref as well.