8000 Optimize `ZIO.fail` by kyri-petrou · Pull Request #9487 · zio/zio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Optimize ZIO.fail #9487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/shared/src/main/scala/zio/Fiber.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
17 changes: 10 additions & 7 deletions core/shared/src/main/scala/zio/ZIO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

/**
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
11 changes: 6 additions & 5 deletions core/shared/src/main/scala/zio/internal/FiberRuntime.scala
Original file line number Diff line number Diff line change
Expand Up @@ -510,12 +510,13 @@ 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
val size = _stackSize // racy

builder += _lastTrace
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this missing from the trace before? Do we have any tests for trace generation?

Copy link
Contributor Author
@kyri-petrou kyri-petrou Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't missing, but because earlier we were going deeper into the runloop stack this would be present in the stack itself. Now since the invocation is flat we have to add it.

Do we have any tests for trace generation

Yes a test failed after updating the code and the fix was to add this here

try {
if (stack ne null) {
var i = (if (stack.length < size) stack.length else size) - 1
Expand Down Expand Up @@ -1221,14 +1222,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
Expand Down
Loading
0