Tracing POC
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
Effectruntime is shared amongst DSL such aseither,result,option,ior, etc thetracedoperator can be added, or used for all these DSLs, and types. Including any of the DSL methods that result in shifting such asensure,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 toShiftCancellationExceptionand the dynamic call toDefaultShift#shiftwhich is not part of the user stack trace. Should we slightly change the API such that this is improved?