Simplify lifecycle definition for classes with init/cleanup method pair
pshirshov opened this issue · comments
It's pretty common to have a resource which can be built with .from[Clz]
but requires .init
to be invoked before it can be used and .cleanup
before it can be released. Both init
and cleanup
are optional.
For now we have to type something like:
(worst-case version)
make[GMStorage].fromResource {
(config: StorageConfig, hash: GMHasher) =>
Lifecycle.make[Identity, GMStorage] {
val out = new GMStorage.GMStorageImpl(config, hash)
out.init()
out
}(_ => ())
}
or
(cleaner but still inconvenient)
make[GMStorage.GMStorageImpl]
make[GMStorage].fromResource {
(underlying: GMStorage.GMStorageImpl) =>
Lifecycle.make[Identity, GMStorage] {
underlying.init()
underlying
}(_ => ())
}
dirty idea:
def makeInitializable[If: Tag, Impl <: If: Tag: AnyConstructor](lifecycle: Impl => Lifecycle[Identity, If]): Unit = {
make[Impl]
make[If].fromResource {
(underlying: Impl) =>
lifecycle(underlying)
}
}
@pshirshov
You may try evalTap
for that:
Lifecycle.makeSimple[GMStorage] {
new GMStorage.GMStorageImpl(config, hash)
}(_ => ())
.evalTap(_.init())
Still, I think that explicit support for a pair of methods would be a good addition
@pshirshov
When you have control of the implementation class you may use Lifecycle.Mutable
for that:
class GMStorageImpl(config: StorageConfig, hash: GMHasher) extends GMStorage with Lifecycle.Mutable {
def acquire: Unit = init()
def release: Unit = ()
}
make[GMStorage].fromResource[GMStorageImpl]
And I've added Lifecycle.makeSimpleInit
#1985 for cases where the implementation class is not controlled:
make[GMStorage].fromResource {
(config: StorageConfig, hash: GMHasher) =>
Lifecycle.makeSimpleInit(
new GMStorageImpl(config, hash)
)(_.init())(_ => ())
}