Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
32 changes: 13 additions & 19 deletions core/jvm-native/src/main/scala/zio/ZIOAppPlatformSpecific.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,16 @@ private[zio] trait ZIOAppPlatformSpecific { self: ZIOApp =>
} yield result).provideLayer(newLayer.tapErrorCause(ZIO.logErrorCause(_)))

runtime.unsafe.run {
ZIO.uninterruptibleMask { restore =>
ZIO.uninterruptible {
for {
fiberId <- ZIO.fiberId
p <- Promise.make[Nothing, Set[FiberId.Runtime]]
fiber <- restore(workflow).onExit { exit0 =>
val exitCode = if (exit0.isSuccess) ExitCode.success else ExitCode.failure
val interrupt = interruptRootFibers(p)
// If we're shutting down due to an external signal, the shutdown hook will fulfill the promise
// Otherwise it means we're shutting down due to normal completion and we need to fulfill the promise
ZIO.unless(shuttingDown.get())(p.succeed(Set(fiberId))) *> interrupt *> exit(exitCode)
fiber <- workflow.interruptible.exitWith { exit0 =>
val exitCode = if (exit0.isSuccess) ExitCode.success else ExitCode.failure
interruptRootFibers(fiberId).as(exitCode)
}.fork
_ <-
ZIO.succeed(Platform.addShutdownHook { () =>
if (!shuttingDown.getAndSet(true)) {
if (shuttingDown.compareAndSet(false, true)) {

if (FiberRuntime.catastrophicFailure.get) {
println(
Expand All @@ -48,28 +44,26 @@ private[zio] trait ZIOAppPlatformSpecific { self: ZIOApp =>
"Check the logs for more details and consider overriding `Runtime.reportFatal` to capture context."
)
} else {
// NOTE: try-catch likely not needed,
// but guarding against cases where the submission of the task fails spuriously
try {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this still need to be in a try?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is an extremely low chance (I can't reproduce, but theoretically it might be possible), that the submission of the task to the executor is rejected (due to shutdown) and throws a RejectedExecutionException.

As I said, I'm not even sure if that's possible but just wanted to be extra safe just in case

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment to clarify

val completePromise = ZIO.fiberIdWith(fid2 => p.succeed(Set(fiberId, fid2)))
runtime.unsafe.run(completePromise *> fiber.interrupt)
fiber.tellInterrupt(Cause.interrupt(fiberId))
} catch {
case _: Throwable =>
}
}

()
}
})
result <- fiber.join
} yield result
_ <- exit(result)
} yield ()
}
}.getOrThrowFiberFailure()
}

private def interruptRootFibers(p: Promise[Nothing, Set[FiberId.Runtime]])(implicit trace: Trace): UIO[Unit] =
private def interruptRootFibers(mainFiberId: FiberId)(implicit trace: Trace): UIO[Unit] =
for {
ignoredIds <- p.await
roots <- Fiber.roots
_ <- Fiber.interruptAll(roots.view.filter(fiber => fiber.isAlive() && !ignoredIds(fiber.id)))
roots <- Fiber.roots
_ <- Fiber.interruptAll(roots.view.filter(fiber => fiber.isAlive() && (fiber.id != mainFiberId)))
} yield ()

}
8 changes: 4 additions & 4 deletions core/shared/src/main/scala/zio/ZIOApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ trait ZIOApp extends ZIOAppPlatformSpecific with ZIOAppVersionSpecific {
*/
final def exit(code: ExitCode)(implicit trace: Trace): UIO[Unit] =
ZIO.succeed {
if (!shuttingDown.getAndSet(true)) {
if (shuttingDown.compareAndSet(false, true)) {
try Platform.exit(code.code)(Unsafe.unsafe)
catch {
case _: SecurityException =>
Expand All @@ -99,8 +99,8 @@ trait ZIOApp extends ZIOAppPlatformSpecific with ZIOAppVersionSpecific {
def runtime: Runtime[Any] = Runtime.default

protected def installSignalHandlers(runtime: Runtime[Any])(implicit trace: Trace): UIO[Any] =
ZIO.attempt {
if (!ZIOApp.installedSignals.getAndSet(true)) {
ZIO.ignore {
if (ZIOApp.installedSignals.compareAndSet(false, true)) {
val dumpFibers =
() => runtime.unsafe.run(Fiber.dumpAll)(trace, Unsafe.unsafe).getOrThrowFiberFailure()(Unsafe.unsafe)

Expand All @@ -109,7 +109,7 @@ trait ZIOApp extends ZIOAppPlatformSpecific with ZIOAppVersionSpecific {
Platform.addSignalHandler("USR1", dumpFibers)(Unsafe.unsafe)
}
}
}.ignore
}
}

object ZIOApp {
Expand Down
Loading