Skip to content

Instantly share code, notes, and snippets.

@cararemixed
Last active June 4, 2018 22:26
Show Gist options
  • Save cararemixed/2ba89df842e7b2baede8edf13a6160fe to your computer and use it in GitHub Desktop.
Save cararemixed/2ba89df842e7b2baede8edf13a6160fe to your computer and use it in GitHub Desktop.
[<RequireQualifiedAccess>]
module Trace =
/// StaticTracer allows tracers to be shared based on type. This allows us
/// to avoid passing the tracer instance explicitly around.
type private StaticTracer<'a>() =
static member val event = Event<'a>()
/// Emit a tracable value by trace type.
let emit<'trace> x =
StaticTracer<'trace>.event.Trigger(x)
/// Subscrive to all values emit for a given trace type.
let subscribe<'trace> f =
StaticTracer<'trace>.event.Publish |> Observable.subscribe f
/// StaticObserver allows a typed group to have unique instances of a
/// StaticTracer. This is also type driven so a phantom type is recommended
/// to avoid confusion.
type private StaticObserver<'group, 'trace>() =
static member val disposable : IDisposable ref = ref null
/// Create a subscription that is linked to a given type. These group
/// types are usually phantom types for topical concerns such as
/// logging or histogram profiles.
let link<'group, 'trace> f =
let disposable = StaticObserver<'group, 'trace>.disposable
lock disposable <| fun () ->
if !disposable <> null then (!disposable).Dispose()
disposable := subscribe<'trace>(f)
/// Dispose of any related subscriptions for a given type. These group
/// types are usually phantom types for topical concerns such as
/// logging or histogram profiles.
let unlink<'group, 'trace>() =
let disposable = StaticObserver<'group, 'trace>.disposable
lock disposable <| fun () ->
if !disposable <> null then (!disposable).Dispose()
disposable := null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment