From 9666c31b3156758557c198ce388b98810720e228 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 20 Jan 2025 16:25:50 +0200 Subject: [PATCH 1/4] Optimize `ZIO.fail` --- core/shared/src/main/scala/zio/Fiber.scala | 8 ++++++++ core/shared/src/main/scala/zio/ZIO.scala | 12 ++++++------ .../src/main/scala/zio/internal/FiberRuntime.scala | 10 +++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/core/shared/src/main/scala/zio/Fiber.scala b/core/shared/src/main/scala/zio/Fiber.scala index 0c81ffd909e5..269f72ad7c55 100644 --- a/core/shared/src/main/scala/zio/Fiber.scala +++ b/core/shared/src/main/scala/zio/Fiber.scala @@ -543,6 +543,13 @@ object Fiber extends FiberPlatformSpecific { */ private[zio] def deleteFiberRef(ref: FiberRef[_]): Unit + /** + * Generates a full stack trace from the reified stack. + * + * '''NOTE''': This method must be invoked by the fiber itself. + */ + private[zio] def generateStackTrace(): StackTrace + /** * Retrieves the current executor that effects are executed on. * @@ -601,6 +608,7 @@ object Fiber extends FiberPlatformSpecific { private[zio] def isAlive(): Boolean + /** * Determines if the specified throwable is fatal, based on the fatal errors * tracked by the fiber's state. diff --git a/core/shared/src/main/scala/zio/ZIO.scala b/core/shared/src/main/scala/zio/ZIO.scala index b195ead4765b..4fcb925cb2b5 100644 --- a/core/shared/src/main/scala/zio/ZIO.scala +++ b/core/shared/src/main/scala/zio/ZIO.scala @@ -3240,12 +3240,12 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific * Returns an effect that models failure with the specified `Cause`. */ def failCause[E](cause: => Cause[E])(implicit trace0: Trace): IO[E, Nothing] = - ZIO.stackTrace(trace0).flatMap { trace => - FiberRef.currentLogSpan.getWith { spans => - FiberRef.currentLogAnnotations.getWith { annotations => - Exit.failCause(cause.applyAll(trace, spans, annotations)) - } - } + ZIO.withFiberRuntime[Any, E, Nothing] { (state, _) => + val trace = state.generateStackTrace() + val refs = state.getFiberRefs(false) + val spans = refs.getOrDefault(FiberRef.currentLogSpan) + val anns = refs.getOrDefault(FiberRef.currentLogAnnotations) + Exit.failCause(cause.applyAll(trace, spans, anns)) } /** diff --git a/core/shared/src/main/scala/zio/internal/FiberRuntime.scala b/core/shared/src/main/scala/zio/internal/FiberRuntime.scala index 185d89764456..c3052d629a92 100644 --- a/core/shared/src/main/scala/zio/internal/FiberRuntime.scala +++ b/core/shared/src/main/scala/zio/internal/FiberRuntime.scala @@ -510,7 +510,7 @@ final class FiberRuntime[E, A](fiberId: FiberId.Runtime, fiberRefs0: FiberRefs, * * '''NOTE''': This method must be invoked by the fiber itself. */ - private def generateStackTrace(): StackTrace = { + private[zio] def generateStackTrace(): StackTrace = { val builder = stackTraceBuilderPool.get() val stack = _stack @@ -1221,14 +1221,14 @@ final class FiberRuntime[E, A](fiberId: FiberId.Runtime, fiberRefs0: FiberRefs, return failure } - case gen0: GenerateStackTrace => - updateLastTrace(gen0.trace) - cur = Exit.succeed(generateStackTrace()) - case updateRuntimeFlags: UpdateRuntimeFlags => updateLastTrace(updateRuntimeFlags.trace) cur = patchRuntimeFlags(updateRuntimeFlags.update, null, Exit.unit) + case gen0: GenerateStackTrace => + updateLastTrace(gen0.trace) + cur = Exit.succeed(generateStackTrace()) + // Should be unreachable, but we keep it to be backwards compatible case update0: UpdateRuntimeFlagsWithin[Any, Any, Any] => assert(DisableAssertions) // Will raise an error in tests but not in released artifact From 53e0782060a5c4315b4992bc8bb796dd93d5f2a7 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 20 Jan 2025 16:32:49 +0200 Subject: [PATCH 2/4] Deprecate `GenerateStackTrace` --- core/shared/src/main/scala/zio/ZIO.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/shared/src/main/scala/zio/ZIO.scala b/core/shared/src/main/scala/zio/ZIO.scala index 4fcb925cb2b5..37df1ab85461 100644 --- a/core/shared/src/main/scala/zio/ZIO.scala +++ b/core/shared/src/main/scala/zio/ZIO.scala @@ -4869,7 +4869,9 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific * Capture ZIO stack trace at the current point. */ def stackTrace(implicit trace: Trace): UIO[StackTrace] = - GenerateStackTrace(trace) + ZIO.withFiberRuntime[Any, Nothing, StackTrace] { (state, _) => + Exit.succeed(state.generateStackTrace()) + } /** * Tags each metric in this effect with the specific tag. @@ -6143,6 +6145,7 @@ object ZIO extends ZIOCompanionPlatformSpecific with ZIOCompanionVersionSpecific def scope(oldRuntimeFlags: RuntimeFlags): ZIO[R, E, A] = f(oldRuntimeFlags) } } + @deprecated("Kept for binary compatibility only", since = "2.1.15") private[zio] final case class GenerateStackTrace(trace: Trace) extends ZIO[Any, Nothing, StackTrace] private[zio] final case class Stateful[R, E, A]( trace: Trace, From fc6cb1dc1a301900ef5d66275c6330aa9c2c2cce Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Tue, 21 Jan 2025 07:13:58 +0200 Subject: [PATCH 3/4] Ensure last trace is added to the StackTrace --- core/shared/src/main/scala/zio/internal/FiberRuntime.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/core/shared/src/main/scala/zio/internal/FiberRuntime.scala b/core/shared/src/main/scala/zio/internal/FiberRuntime.scala index c3052d629a92..f36a94665a68 100644 --- a/core/shared/src/main/scala/zio/internal/FiberRuntime.scala +++ b/core/shared/src/main/scala/zio/internal/FiberRuntime.scala @@ -516,6 +516,7 @@ final class FiberRuntime[E, A](fiberId: FiberId.Runtime, fiberRefs0: FiberRefs, val stack = _stack val size = _stackSize // racy + builder += _lastTrace try { if (stack ne null) { var i = (if (stack.length < size) stack.length else size) - 1 From f3b02ccf2475f6f4863844f1b7b81994d1864c40 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Wed, 22 Jan 2025 03:42:22 +0200 Subject: [PATCH 4/4] fmt --- core/shared/src/main/scala/zio/Fiber.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/core/shared/src/main/scala/zio/Fiber.scala b/core/shared/src/main/scala/zio/Fiber.scala index 269f72ad7c55..dd32d254139f 100644 --- a/core/shared/src/main/scala/zio/Fiber.scala +++ b/core/shared/src/main/scala/zio/Fiber.scala @@ -608,7 +608,6 @@ object Fiber extends FiberPlatformSpecific { private[zio] def isAlive(): Boolean - /** * Determines if the specified throwable is fatal, based on the fatal errors * tracked by the fiber's state.