ZIO stuff we should all be familiar with
(...) a data structure that encapsulates the acquisition and the release of a resource.
While creating an A you will need to provide an environment R and you may have an error of type E
While creating an A you will need to provide an environment R and you may have an error of type E
While creating an A you will need to provide an environment R and you may have an error of type E
ZManaged
.make {
for {
config <- ZIO.environment[DynamoConfig]
client <- ZIO.effect {
DynamoDbAsyncClient
.builder()
.region(Region.of(config.signingRegion))
.endpointOverride(config.endpoint)
.build()
}
} yield client
} { client =>
ZIO.effectTotal(client.close())
} : ZManaged[DynamoConfig, Throwable, DynamoDbAsyncClient]
See Main.scala in subv2 service
(...) express an effect's dependency on a service of type A. For example, RIO[Has[Console.Service], Unit] is an effect that requires a Console.Service service.
Essentially: a way to combine different values.
val repo: Has[Repo.Service] = Has(new Repo.Service{})
val logger: Has[Logger.Service] = Has(new Logger.Service{})
val mix: Has[Repo.Service] with Has[Logger.Service] = repo ++ logger
Common in some signatures.
Evidence that a type A is a service (there is some X = Has[A])
ZLayer[-RIn, +E, +ROut <: Has[_]] is a recipe to build an environment of type ROut, starting from a value RIn, possibly producing an error E during creation.
ZLayer[-RIn, +E, +ROut <: Has[_]] is a recipe to build an environment of type ROut, starting from a value RIn, possibly producing an error E during creation.
trait ZIO[R,E,A] {
// simplified signature
def provideLayer[E, R0, R](layer: ZLayer[R0, E, R]): ZIO[R0, E, A]
}
val layer: ZLayer[DynamoConfig, Error, DynamoAsync] = ???
val operation: ZIO[DynamoAsync, Error, DynamoGetResponse] = ???
val operation2: ZIO[DynamoConfig, Error, DynamoGetResponse] = operation.provideLayer(layer)
val dynamoConfig: DynamoConfig = ???
val operation3: ZIO[Any, Error, DynamoGetResponse] = operation2.provide(dynamoConfig)
ZLayer[-RIn, +E, +ROut <: Has[_]] is a recipe to build an environment of type ROut, starting from a value RIn, possibly producing an error E during creation.
Simplest constructors:
ZLayer[-RIn, +E, +ROut <: Has[_]] is a recipe to build an environment of type ROut, starting from a value RIn, possibly producing an error E during creation.
Simplest constructors:
Effectful variations, when the function returns a ZIO:
ZLayer[-RIn, +E, +ROut <: Has[_]] is a recipe to build an environment of type ROut, starting from a value RIn, possibly producing an error E during creation.
Simplest constructors:
"service" variations, when the layer input A is a service (requires a Has[A]):
Effectful variations, when the function returns a ZIO:
Managed variations:
Managed variations:
Managed variations:
type RLayer[-RIn, +ROut] = ZLayer[RIn, Throwable, ROut]
type URLayer[-RIn, +ROut] = ZLayer[RIn, Nothing, ROut]
type Layer[+E, +ROut] = ZLayer[Any, E, ROut]
type ULayer[+ROut] = ZLayer[Any, Nothing, ROut]
type TaskLayer[+ROut] = ZLayer[Any, Throwable, ROut]
object DynamoAsync {
// ...
val live: ZLayer[Has[DynamoConfig], Throwable, DynamoAsync] =
ZLayer.fromServiceManaged { config: DynamoConfig =>
ZManaged
.makeEffect {
DynamoDbAsyncClient
.builder()
.region(Region.of(config.signingRegion))
.endpointOverride(config.endpoint)
.build()
} { client =>
ZIO.effectTotal(client.close())
}
.map { dynamoDbAsyncClient =>
new DynamoLive(
dynamoDbAsyncClient,
config.subscriptionsTableName
): DynamoAsync.Service
}
}
}
object Logging {
val consoleLogger: ZLayer[Console, Nothing, Logging] = ???
}
object UserRepo {
val inMemory: Layer[Nothing, UserRepo] = ???
}
// compose horizontally
val horizontal: ZLayer[Console, Nothing, Logging with UserRepo] =
Logging.consoleLogger ++ UserRepo.inMemory
Console.live: ZLayer[Any, Nothing, Console] = ???
// fulfill missing deps, composing vertically
val fullLayer: Layer[Nothing, Logging with UserRepo] =
Console.live >>> horizontal
val logWhatever: ZIO[Console, Nothing, Unit] = logInfo("whatever")
val dbQuery: ZIO[DynamoAsync, , Nothing, Unit] = ???
for {
_ <- logWhatever
result <- dbQuery
} yield result
==== logWhatever *> dbQuery
See Main in subscription-commands-processor