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

Skip to content

Conversation

@hearnadam
Copy link
Collaborator

@hearnadam hearnadam commented Nov 22, 2025

I noticed that in libraries that use Runtime.unsafe to create Fibers, the Unsafe allocation can actually be non-trivial. This change introduces a new abstract class to cache an instance in a var. I initially used a val, but ran into some class instantiation issues.

I added a prettified toString method to render the Runtime

Before:

scala> zio.Runtime.default
val res0: zio.Runtime[Any] = zio.Runtime$$anon$3@22824450

After:

scala> zio.Runtime.default
val res1: zio.Runtime[Any] = Runtime(environment = ZEnvironment(), fiberRefs = FiberRefLocals(), runtimeFlags = RuntimeFlags(Interruption, CooperativeYielding, FiberRoots))

@hearnadam hearnadam force-pushed the runtime-class branch 4 times, most recently from c6126d1 to e507824 Compare November 23, 2025 04:03
- Add a prettified `toString` method to render the Runtime

Before:
```
scala> zio.Runtime.default
val res0: zio.Runtime[Any] = zio.Runtime$$anon$3@22824450
```

After:
```
scala> zio.Runtime.default
val res1: zio.Runtime[Any] = Runtime(environment = ZEnvironment(), fiberRefs = FiberRefLocals(), runtimeFlags = RuntimeFlags(Interruption, CooperativeYielding, FiberRoots))
```
Comment on lines +218 to +221
override def unsafe: UnsafeAPI with UnsafeAPI3 = {
if (unsafe0 eq null) unsafe0 = new UnsafeAPIV1 {}
unsafe0
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is unfortunately necessary as directly instantiating a val can cause issues with the order of instantiation:

error: scala-k8s.md:101:1: Cannot invoke "zio.FiberRef.initial()" because "fiberRef" is null
val nodes = ZIOKubernetesClient.send(APIs.nodes.list())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
java.lang.ExceptionInInitializerError
	at zio.FiberRef$.<clinit>(FiberRef.scala:599)
	at zio.ZIO$ServiceWithZIOPartiallyApplied$.apply$extension(ZIO.scala:5722)
	at zio.ZIO$ServiceWithPartiallyApplied$.apply$extension(ZIO.scala:5711)
	at zio.ZIO$.service(ZIO.scala:4750)
	at dev.hnaderi.k8s.client.ZIOKubernetesClient$.send(ZIOKubernetesClient.scala:30)
	at repl.MdocSession$MdocApp.<init>(scala-k8s.md:17)
	at repl.MdocSession$.app(scala-k8s.md:3)
Caused by: java.lang.NullPointerException: Cannot invoke "zio.FiberRef.initial()" because "fiberRef" is null
	at zio.FiberRefs.getOrDefault(FiberRefs.scala:150)
	at zio.Runtime$UnsafeAPIV1.<init>(Runtime.scala:125)
	at zio.Runtime$$anon$3$$anon$4.<init>(Runtime.scala:245)
	at zio.Runtime$$anon$3.<init>(Runtime.scala:245)
	at zio.Runtime$.apply(Runtime.scala:241)
	at zio.Runtime$.<clinit>(Runtime.scala:254)```

new UnsafeAPIV2 {}

override def unsafe: UnsafeAPI with UnsafeAPI2 with UnsafeAPI3 = {
if (unsafe0 eq null) unsafe0 = new UnsafeAPIV2 {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we need to cache this? We could unsafely set the type of unsafe0 to Object (which is what UnsafeAPI with UnsafeAPI2 with UnsafeAPI3 is compiled to anyways)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean cache this? that's what the assignment is doing?

Copy link
Contributor

Choose a reason for hiding this comment

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

I did not read it correctly, nevermind me 🤦

@kyri-petrou kyri-petrou merged commit 36eba74 into zio:series/2.x Nov 28, 2025
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants