Taps
Taps observe transitions between tors — logging, metrics, or tracing as a detached layer, without modifying the flow being watched. The tap syntax is:
tap(from -> to) | branch b [when condition] |> ... Taps support wildcards and module filtering. If the destination is a wildcard, the tor’s interface is unknown, and you will be presented with a meta-type Transition. Taps are non-exhaustive, and you can filter them using the when clause.
Reading taps
A mental model of taps is that they are a way to observe the flow of your application — to see what is happening inside it, and to understand how it is working.
Example:
tap(db:store-transaction -> ui:show-success) | success s |> log(text: s.message) This reads as: when the program flow transitions from db:store-transaction to ui:show-success, log the success-message.
Concrete examples
tap(player:hit -> *) | player-hit ph when ph.damage > 40 |> audio:play-sound("aargh.wav")
tap(player:hit -> *) | player-hit ph when ph.damage > 80 |> particles:emit-blood-fountain() You can have multiple taps on the same tor with different conditions.
Metatype Examples
Do full auditing of all tors.
tap(* -> *) | Audit a |> log(a) Transition Metatypes
Transition Metatypes capture metadata about transitions between tors — information such as the duration, the source and destination tors, and the branch taken.
There are different types of transition metatypes, including Transition, Profile, and Audit. Each type of transition metatype has its own set of fields that can be used to capture information about the transition.
Transition- lightweight datatype capturing source/destination and branch-name as enumsProfile- lightweight datatype capturing source/destination and branch as pointers to interned strings, timestamp, and other profiling informationAudit- Heavy datatype capturing source/destination and branch-name as pointers to interned strings, timestamp, transition payloads and other audit information
You can always use a transition metatype to capture metadata about a transition, instead of capturing concrete branch data.
Transition Metatypes are used in taps to capture metadata about transitions instead of branch payloads. When writing a tap, you can choose to bind to:
- Concrete branch data:
| done |>- receives the payload from that branch - Transition metadata:
| Transition t |>- receives metadata about the transition
Forced Metatypes
When the source tor in a transition is described using wildcards, you cannot know its continuation branches, therefore you are forced to use a transition metatype to capture the metadata between the source and destination tors.
If the destination tor is also described using wildcards but the source tor is concrete, you can use a concrete continuation branch to capture the case.