Skip to content
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

Simplify lifecycle definition for classes with init/cleanup method pair #1942

Closed
pshirshov opened this issue May 8, 2023 · 3 comments
Closed
Assignees

Comments

@pshirshov
Copy link
Member

pshirshov commented May 8, 2023

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)
    }
  }
@neko-kai
Copy link
Member

neko-kai commented May 8, 2023

@pshirshov
You may try evalTap for that:

Lifecycle.makeSimple[GMStorage] {
  new GMStorage.GMStorageImpl(config, hash)
 }(_ => ())
  .evalTap(_.init())

@pshirshov
Copy link
Member Author

Still, I think that explicit support for a pair of methods would be a good addition

neko-kai added a commit that referenced this issue Jul 6, 2023
@neko-kai
Copy link
Member

neko-kai commented Jul 6, 2023

@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())(_ => ())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants