Sign in
Log inSign up
Pierre Ricadat

4 likes

·

1.6K reads

1 comment

Calvin Fernandes
Calvin Fernandes
Nov 11, 2024

Great explanation Pierre!

if I may humbly add a few points. ZLayers force you to model your dependencies explicitly as well as think about your constructors. Constructors (and their dependencies) may be effectful in nature (i.e opening a database connection/creating a pool of connections). Not only this, but there is a lifecycle associated with each resource and their dependencies.

When you say

val deps: ZLayer[Any, Nothing, Dep]
effect.provide(deps)

What you are doing is initializing dependencies whose lifecycle(s) are bound to the effect. As soon as the effect completes, the dependencies are torn down.

Another way to look at it is ZLayers are essentially categorical arrows - they are powerful enough to represent functions through receiving arguments/dependencies as R, fail with an E and produce an A, in ZLayer[R, E, A] where ZIO.scoped { R => ZIO[Scope, E, A] } where it will take care of managing the Scope for you (keeping the dependencies open for as long your effect needs).

The main points to focus on here

  • ZLayers are just as powerful as functions
  • ZLayers handle lifecycle management for your dependencies compositionally ensuring resources and their dependencies lifecycles are appropriately spun up and torn down

You may think that ZLayers are complex but try to do all of this without compositional lifecycle resource management - you'll soon find you are in a world of pain

3
·