-
Couldn't load subscription status.
- Fork 1.4k
Automatic ZLayer derivation #8374
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
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.
Couple of specific comments but overall looks great!
|
Added support for parameterized polymorphism in 5d55e65. The Scala 3 part was much harder than I thought... |
|
Addressed all feedbacks. |
|
|
||
| def acquire: ZIO[R, E, Any] | ||
|
|
||
| def release: ZIO[R, Nothing, Any] |
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.
Should release have access to the acquired resource?
trait AcquireRelease[-R, +E] extends Scoped[R, E] {
type A
final def scoped(implicit trace: Trace): ZIO[R & Scope, E, Any] =
ZIO.acquireRelease(acquire)(release)
def acquire: ZIO[R, E, A]
def release(a: A): ZIO[R, Nothing, Any]
}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.
How about just AcquireRelease[-R, +E, A]? A not being covariant is a bit inconsistent with the other datatypes but it's simpler.
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.
Here's the revised example with the new design:
import zio._
import java.io.File
def acquireLockFile(path: String): ZIO[Any, Throwable, File] = ???
def deleteFile(file: File): ZIO[Any, Throwable, Unit] = ???
class ASingletonService(lockFilePath: String) extends ZLayer.Derive.AcquireRelease[Any, Throwable, File] {
override def acquire: ZIO[Any, Throwable, File] =
acquireLockFile(lockFilePath)
override def release(lockFile: File): ZIO[Any, Nothing, Any] =
deleteFile(lockFile).ignore
}|
@adamgfraser Could you take another look? |
|
@guersam I like it! |
| * `ZLayer.Default[A]` to ensure correct type inference and dependency | ||
| * resolution during `ZLayer` derivation. | ||
| */ | ||
| trait Default[+A] { |
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 could probably be moved into the Derive companion object since like Scoped and AcquireRelease it really only has meaning within the context of derive.
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 thought about it too, but unlike Scoped sometimes it might be used like Default[A].layer without ZLayer.derive. What do you think?
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.
Besides the possible independent use case, putting Default inside of Derive can imply that the layer derivation process is aware of Default.
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 tend to think there is not a use of Default independent of derive. Theoretically the concept of a default value could make sense in other contexts but practically there is nothing else that uses it and the fact that a default value could itself by constructed from a layer makes it very specific to the derivation.
I don't understand your comment about the derivation process being aware of default. The derivation process is aware of default in that if you construct something that has like a Ref where are going to look for a default value for the value inside the Ref. So the default values are intimately related to derivation and in fact derivation is the reason for their existence.
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.
Agreed. I mean when we put Default in Derive it will reveal that relationship more explicitly. I'll move it into Derive.
|
|
||
| object Derive { | ||
|
|
||
| /** |
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.
Documentation could be updated here to reflect the changes we have made.
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.
Updated Scaladoc.
| If you're uncertain about the exact type signature, a practical approach is to omit the type annotation initially. Then, | ||
| use your IDE's autocomplete feature to insert the inferred type. | ||
|
|
||
| ## Lifecycle Hooks |
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.
Same here.
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.
Looks great! Just a few minor comments.
257fd14 to
c0196c5
Compare
58f1e7e to
7e21b1b
Compare
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.
@adamgfraser Applied the latest feedback in 7e21b1b.
|
|
||
| object Derive { | ||
|
|
||
| /** |
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.
Updated Scaladoc.
| * `ZLayer.Default[A]` to ensure correct type inference and dependency | ||
| * resolution during `ZLayer` derivation. | ||
| */ | ||
| trait Default[+A] { |
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.
Moved under ZLayer.Derive.
| `A` implements the `ZLayer.Derive.Scoped[-R, +E]` trait, `ZLayer.derive[A]` automatically recognizes it. As a result, | ||
| the `scoped` effect is executed during the layer's construction and finalization phases. | ||
|
|
||
| The 'resource' might be a background task, a lock file, or etc., that can be managed by [`Scope`](../resource/scope.md). |
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.
Improved doc about Scoped with an example.
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.
Looks great! Thanks for your work on this!
/claim #8106
This PR adds fully working implementation of
ZLayer.derive, including:ZLayer.Default[A]ZIO.configwhen an implicitConfig[A]existsZLayer.LifecycleHooks[R, E]