-
Couldn't load subscription status.
- Fork 1.4k
Implement ZManaged.memoize
#2016
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.
Hi @mlangc, sorry this waited in the PR queue for so long. The changes look good to me - I left two minor comments.
Could you address them and rebase? I'll merge afterwards. Thanks for working on this useful combinator!
| val release1 = (_: Exit[_, _]) => ZIO.unit | ||
|
|
||
| val acquire2: ZIO[R, E, ZManaged[R, E, A]] = | ||
| ZIO.succeed(ZManaged(ZIO.succeed(Reservation(acquire1, release1)))) |
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.
| ZIO.succeed(ZManaged(ZIO.succeed(Reservation(acquire1, release1)))) | |
| ZIO.succeed(acquire1.toManaged_) |
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 looks better indeed - thanks for spotting
| case Some(cause) => onDefect(cause) | ||
| case None => | ||
| update(a).foldM(e => onDefect(Cause.fail(e)) <* promise.fail(e), { | ||
| update(a).foldCauseM(c => onDefect(c).ensuring(promise.halt(c)), { |
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.
Can you add a test for this change?
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.
Of course, I will look into this over the weekend.
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've just added a test (see fecf6b4). Without the change from above, this test times out.
1cd7efc to
cb705f3
Compare
|
@iravid thanks for the review. Strangely enough, rebasing introduced a regression: I will investigate over the weekend, but if you have an idea about the possible cause let me know. |
|
It's probably related to the autosupervision work. Another suggestion before you dive into this: I think you can replace RefM with a Ref and a Semaphore. It's a simpler mechanism that is easier to introspect and figure out what goes wrong; RefM has a bunch of moving parts that make it harder to diagnose problems in. |
|
Thanks for the hints, I'll take that into consideration! I'm still wondering if the regression I see is because of a subtle, intended semantic change, or a because of a regression in another component. |
cb705f3 to
545768b
Compare
|
@iravid I found out more about the test running into a timeout after rebasing with auto supervision: The reason was not that finalizers where not run, but that Note that I can still look into dropping |
|
@mlangc Ah good catch. Yes, that's one of the "intricacies" with RefM. It may make sense to mark that consumer fiber as If you don't want to wait, I would suggest just getting rid of RefM in this combinator for now. |
|
Actually, I think marking that fiber as |
|
Ok, sounds good - thanks for your work on this @mlangc. Will merge when CI is done. |
* Implement `ZManaged.memoize` Fixes zio#1263 * Correctly handle fatal errors in `RefM` * Simplify implementation * Fix test timeout after rebasing with auto supervision * Add a test that that verifies that `RefM` handles fatal errors * Make internal `RefM` fiber a daemon fiber and adapt test * Add test that uses `RefM` after interrupting its parent fiber
Originally, I tried to implement this like
ZIO.memoize. While this approach looks mean and lean for the happy path, getting this right for fatal errors and interruptions is far less trivial (see mlangc@016e264#diff-ba99038d96380b834448ea7c9ddd3c05R776 to get an impression).The current implementation uses a different approach, that is based on a
RefM(this PR also fixes aRefMbug related to fatal errors that hit me). Maybe a normalReftogether with one or morePromisescould be used too, at the cost of added complexity.One last note on the naming: I choose
ZManaged.memoizeoverZManaged.shared, to emphasize thatZManaged.memoizecorresponds directly toZIO.memoize. Also,sharedreminds me of reference counters (maybe from my old C++ times), and might be used to implement different semantics in the future.Fixes #1263