Event Taps

You can set up Event Taps to observe transitions between event continuations. The tap syntax is:

~[annotations]tap(from -> to) | branch b [when condition] |> ...

Event Taps support wildcards and module filtering. If the destination is a wildcard, the event interface is unknown, and you will be presented with a meta-type Transition. Event Taps are non-exhaustive, and you can filter them using the when clause.

Reading event taps

A mental model of event taps is that they are a way to observe the flow of events in your application. They are a way to see what is happening in your application, and to understand how your application is working.

Example:

~[profile]tap(db:store_transaction -> ui:show_success) | success s |> log(text: s.message)

This reads as: With compiler annotation profile, 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 event taps on the same event continuation with different conditions.

Metatype Examples

Do full auditing of all events.

~[audit]tap(* -> *) | Audit a |> log(a)

Transition Metatypes

Transition Metatypes are used to capture metadata between event continuations. They are used to represent the transition between two event continuations, and can be used to capture information about the transition, such as the duration, the source and destination event continuations, 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 enums
  • Profile - lightweight datatype capturing source/destination and branch as pointers to interned strings, timestamp, and other profiling information
  • Audit - 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 between event continuations, instead of capturing concrete branch data.

Transition Metatypes are used in event 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 event in a transition is described using wildcards, you cannot know the continuation branches from the source events, therefore you are forced to use a transition metatype to capture the metadata between the source and destination event continuations.

If the destination event continuation is also described using wildcards but the source event is concrete, you can use a concrete continuation branch to capture the case.