-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Runtime: use Internal abstract class to make unsafe a val
#10250
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
Conversation
c6126d1 to
e507824
Compare
- 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)) ```
e507824 to
5cbc36d
Compare
| override def unsafe: UnsafeAPI with UnsafeAPI3 = { | ||
| if (unsafe0 eq null) unsafe0 = new UnsafeAPIV1 {} | ||
| unsafe0 | ||
| } |
There was a problem hiding this comment.
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 {} |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 🤦
I noticed that in libraries that use
Runtime.unsafeto 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 aval, but ran into some class instantiation issues.I added a prettified
toStringmethod to render the RuntimeBefore:
After: