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))
=> nilFrees 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/nilThis 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)
=> nilMakes 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))
=> eventRun 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))
=> eventSyntax 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-closureLike delay, but runs the given callback every time seconds until
stopped by either funcalling the returned closure, or calling remove-inteval
on the returned closure.
with-interval
(defmacro with-interval ((seconds) &body body))
=> cancel-closureSyntax wrapper around interval. Returns the same cancellation
closure that interval does.
remove-interval
(defun remove-interval (interval-closure))
=> nilWhen given the closure returned from calling interval, stops the timer on the interval (cancels it).
make-event
(defun make-event (callback &key event-cb))
=> eventMakes 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)))
=> nilReferences 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)))
=> nilUnreferences 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.