arrow icon indicating copy to clipboard operation
arrow copied to clipboard

Tracing POC

Open nomisRev opened this issue 3 years ago • 0 comments

Discussing some ideas for new features with @raulraja he mentioned tracing for Effect, so I was playing around with some ideas and come up with a small POC.

Since shift already relies on CancellationException to co-operate with the coroutine system we currently pay a performance penalty for shift and the stack trace creation that comes with CancellationException by default. This penalty is not needed, and is stack trace creation is by default also disabled in KotlinX Coroutines.

This PR solves the issue of debugging/tracing, and the performance penalty we currently pay for shift. We can now disable the stack trace creation, and we can ad-hoc enable it for any Effect you compose traced upon or any Shift program you run within a traced block.

public fun main() {
  val error = effect<String, Int> { shift("error") }
  error.traced { traced -> traced.printStackTrace() }
    .fold({ require(it == "error") }, { error("impossible") })
}
arrow.core.continuations.ShiftCancellationException: Shifted Continuation
  at arrow.core.continuations.DefaultShift.shift(Fold.kt:77)
  at MainKtKt$main$error$1.invoke(MainKt.kt:6)
  at MainKtKt$main$error$1.invoke(MainKt.kt:6)
  at arrow.core.continuations.Shift$DefaultImpls.bind(Shift.kt:22)
  at arrow.core.continuations.DefaultShift.bind(Fold.kt:74)
  at arrow.core.continuations.Effect__TracingKt$traced$2.invoke(Tracing.kt:46)
  at arrow.core.continuations.Effect__TracingKt$traced$2.invoke(Tracing.kt:46)
  at arrow.core.continuations.Effect__FoldKt.fold(Fold.kt:92)
  at arrow.core.continuations.Effect.fold(Unknown Source)
  at MainKtKt.main(MainKt.kt:8)
  at MainKtKt.main(MainKt.kt)

Notes

  • Since the Effect runtime is shared amongst DSL such as either, result, option, ior, etc the traced operator can be added, or used for all these DSLs, and types. Including any of the DSL methods that result in shifting such as ensure, ensureNotNull, bind, etc.

  • Currently only JVM is disabling stack-trace generation. Not sure if we also need to disable it for JS, or Native. (KotlinX Coroutines only disables it for JVM)

  • What API would we want on Traced<R>? Currently we include mentions to ShiftCancellationException and the dynamic call to DefaultShift#shift which is not part of the user stack trace. Should we slightly change the API such that this is improved?

nomisRev avatar Sep 03 '22 10:09 nomisRev