-
Notifications
You must be signed in to change notification settings - Fork 58
Event Bus
The event-bus can be used to pass around or react to events happening in LambdaCD, such as updates to the state of a pipeline run.
It's based on the core.async pub/sub abstraction (a good introduction can be found here).
A few things to keep in mind when working with the event-bus:
- Subscriptions are unordered and parallel: You can not assume that other event-handlers already processed the same event
- Subscriptions block the publisher: If you are subscribing to an event, make sure you process it quickly as the publisher is only unblocked after all subscribers processed the event
The main entry-point is the lambdacd.event-bus namespace with convenience-functions to publish and subscribe to events:
-
publish [ctx topic payload]
: Publishes an event with a givenpayload
for a particulartopic
-
subscribe [ctx topic]
: Returns a channel with a subscription for events with the giventopic
. The events on this channel contain thepayload
and metadata about the event (e.g. thetopic
) -
only-payload [subscription]
: Takes a channel (usually the result ofsubscribe
) and returns a channel that contains only the payload for the event -
unsubscribe [ctx topic subscription]
: Unsubscribe from a topic. Takes the result ofsubscribe
and thetopic
subscribed to
Currently, the following topics are provided by LambdaCD:
-
:step-finished
: Event that gets triggered after a build step is finished. Can be used to trigger notifications in other systems or to react a finished build step. For example used by runners to determine when to start a new pipeline-run. The payload looks like this:{:build-number 3 :step-id `(1 2 3) :final-result {:status :success :foo :baz}}
-
:step-result-updated
: Event that gets triggered whenever a step updates it's result. For example used by pipeline-state components to save updates to the pipeline state to disk. As event-handlers are unordered, you can not assume that these components already processed this event. Look at:step-result-update-consumed
as an alternative. The payload looks like this:
{:build-number 3 :step-id `(1 2 3) :step-result {:status :running}}
* `:step-result-update-consumed`: Event that gets triggered whenever a step-result update has been consumed by the pipeline state component. Pipeline is the same as `:step-result-updated`. Prefer this event over `:step-result-updated` if you expect the update to be present in the pipeline state. (introduced in 0.11.0)
* `:pipeline-started`: Event that gets triggered whenever a new build-pipeline gets started (this includes retriggered builds). (introduced in 0.13.0) The payload looks like this:
```clojure
{:build-number 10}
-
:pipeline-finished
: Event that gets triggered whenever a build-pipeline finishes. (introduced in 0.13.0) The payload looks like this:{:build-number 10 :status :success :outputs {[1] {:status :success :step 1} [2] {:status :success :step 2}}}
Build pipelines or components can define their own classes of events just by publishing events to a topic of their choosing. For example, the manual trigger uses this to notify build steps waiting for a user interaction once the user has clicked the trigger button in the UI.
; Print all events to topic :foo-topic
(ns events-example.core
(:require
[lambdacd.core :as lambdacd]
[lambdacd.event-bus :as event-bus]
[clojure.core.async :as async]))
(defn print-all-foo-events [ctx]
(let [subscription (event-bus/subscribe ctx :foo-topic)
steps-finished (event-bus/only-payload subscription)]
(async/go-loop []
(if-let [event (async/<! steps-finished)]
(do
(println event)
(recur))))))
(defn -main [& args]
(let [pipeline (lambdacd/assemble-pipeline pipeline/pipeline-def config)]
; ...
(print-all-foo-events (:context pipeline))))
; Publishing an event on :foo-topic
(ns events-example.steps
(:require [lambdacd.event-bus :as event-bus]))
(defn some-step-that-publishes-foo [args ctx]
(event-bus/publish ctx :foo-topic {:some :data})
{:status :success})