-
Couldn't load subscription status.
- Fork 41
Cache managed resource #71
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
|
I think you are definitely on the right track. The signature would likely have to change like this: sealed trait ManagedCache[-Key, +Error, +Value] {
def lookup(key: Key): ZManaged[Any, Error, Value]
}
object ManagedCache {
def make[Key, Environment, Error, Value](lookup: Key => ZManaged[Environment, Error, Value]): ZManaged[Environment, Nothing, ManagedCache[Key, Error, Value] =
???
}The You can look at the implementation of the |
|
@adamgfraser Thank you a lot for your answer. Do you also mean I should in the final solution merge |
|
I don't think there is any need for |
f5b3ab9 to
f4d0c49
Compare
1b1876e to
7d69a66
Compare
|
To go further on my work I think I need to add some unit test about expiration, I think this would be way easier if ManagedCache used |
|
@strokyl The functionality to use the |
To be honest, I am working on this feature also because my team need it and so far with still on ZIO 1. I would prefer to firstly target ZIO 1 for this PR and after we work on making it use |
|
Okay. We are generally doing all new development on ZIO 2.0 but you are welcome to target your PR against whatever version you want. 😃 |
That sweet :). I wish I will find time to contribute later the migration of this code to ZIO 2.0, and I will probably because sooner or later my team will move to ZIO 2.0 (pretty soon I wish). But while doing a test about expiration, I wonder what is better:
I have the feeling |
c1b0c15 to
7b0b659
Compare
|
Ok so I think my PR is now ready to review, I try to make reviews easier by the way I organize commits. In fact, my approach to code this feature was:
The point was to make it easy to see how the cache code was adapted in the last commit. |
| def entryStats(key: Key): UIO[Option[EntryStats]] | ||
|
|
||
| /** | ||
| * Give a proxy managed on the resource already created for this key if any. |
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 would more conceptualize this as "gets the value from the cache if it exists or otherwise computes it, the release action signals to the cache that the value is no longer being used and can potentially be finalized subject to the policies of the cache".
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.
Went for:
/**
* Return a managed that gets the value from the cache if it exists or otherwise computes it, the release action
* signals to the cache that the value is no longer being used and can potentially be finalized subject to the
* policies of the cache
* @param key
* @return
*/
Thought return a managed was important, because I want to make sure user understand all of that is happening only once he use the returned Managed
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.
Okay but that is true for every value in ZIO. Regardless of whether it is a ZManaged or a ZIO nothing happens unless it is evaluated. So at least to me it is confusing in that it implies that something different is going on here whereas what is going on is exactly the same as everything else in ZIO. One thing we should make sure of here is that it should not even look up the value in the cache until the ZManaged is evaluated since otherwise that would be a violation of referential transparency.
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.
Okay but that is true for every value in ZIO. Regardless of whether it is a ZManaged or a ZIO nothing happens unless it is evaluated.
That is a really good point, and it make me reconsider the change I did to your proposal. In fact, specifying here the normal behaviour of ZIO is confusing, I went back to your exact proposition.
One thing we should make sure of here is that it should not even look up the value in the cache until the ZManaged is evaluated since otherwise that would be a violation of referential transparency.
I already had test about making sure that the value isn't lookup before the ZManaged is evaluated! But I didn't about checking that contains is returning false before the ZManaged is evaluated, I just added one
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.
Minor comments on documentation but otherwise looks good!
Thank you for the review, I adapted the documentation in a new separated commit, tell me if this is ok for you and then we can merge the PR! |
|
@strokyl Can you merge upstream changes? |
Because they probably going to be shared with ManagedCache
…aged[Error, Value]]
f9879d4 to
2342d7d
Compare
|
I can't merge this PR because of: |
|
Ok so I follow this procedure: From: https://dev.folio.org/guidelines/cla-process/ and now it's all green |
* Implement Cache#invalidateAll (#51) * implement Cache#invalidateAll * format * Added size to `CacheStats`. (#53) * Added size and capacity to `CacheStats`. * Removed `capacity` from stats. * Update Node.js to v14.18.0 (#55) Co-authored-by: Renovate Bot <[email protected]> * Add `refresh` method to trigger a lookup call. (#52) * First attempt to resolve #42 * Fixed a concurrency issue * Refactoring * Minor refactorings, scalafmt & sbt upgrades * Fixing build * Refactoring: replaced vars with ref * Reformatted build.sbt to fix build. * Fixing build * Fixing build * Updated docs * Fixed formatting and addressed PR comments. * Fixed docs * Added a unit test for `refresh` method. * Improved docs * Minor improvement * Bumped scalafmt * Bumped scalajs * Update Node.js to v14.18.1 (#58) Co-authored-by: Renovate Bot <[email protected]> * Update actions/checkout action to v2.3.5 (#59) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16 (#61) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.13.0 (#62) Co-authored-by: Renovate Bot <[email protected]> * Update actions/checkout action to v2.4.0 (#64) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.13.1 (#65) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.13.2 (#68) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.14.0 (#70) Co-authored-by: Renovate Bot <[email protected]> * Update actions/checkout action (#72) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.14.1 (#73) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.14.2 (#74) Co-authored-by: Renovate Bot <[email protected]> * Update hmarr/auto-approve-action action to v2.2.0 (#77) Co-authored-by: Renovate Bot <[email protected]> * Update actions/checkout action to v3.0.1 (#82) Co-authored-by: Renovate Bot <[email protected]> * Update actions/checkout action to v3.0.2 (#83) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.15.0 (#84) Co-authored-by: Renovate Bot <[email protected]> * Update Node.js to v16.15.1 (#87) Co-authored-by: Renovate Bot <[email protected]> * Cache managed resource (#71) * Add .bsp to .gitignore * Extract KeySet and MapKey out of Cache Because they probably going to be shared with ManagedCache * define interface for a ManagedCache * Copy/Paste: cache implementation and cache test for managedCache * Adapt cache implementation and test for ManagedCache * make ManagedCache.get return Managed[Error, Value] instead of UIO[Managed[Error, Value]] * Make ManagedCache work on 2.11 and Scala 3 * Fix doc after Adam's review * fixup! Fix doc after Adam's review * fixup! Fix doc after Adam's review * fix managed cache invalidate not being lazy (#88) * run finalizer after acquire fails * fix compilation issue * format Co-authored-by: Adam Fraser <[email protected]> Co-authored-by: Terry L <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Renovate Bot <[email protected]> Co-authored-by: LUC DUZAN <[email protected]>
I start working on #50:
But I realize that the cache can't just call the release action when the key is evicted because there is no way to know if fibers that acquired the resource are done with it.
To make it work I think the cache should keep track of the number of fibers using the value for that the
getwould return aManaged[Error, Value]instead ofIO[Error, Value], so fibers using value would call a releaser and therefore inform there are done with this value.At first, I wanted to work on that logic (keeping track of how many fibers currently using a resource in order to clean it at the correct time) without having to think about key and expiration details.
I come with this
SharedManagedlogic that wraps a regularManagedand provides proxiedManagedfor it in a way the underlying managed is only created once and cleaned once.I wrote some code for that and some tests. But because concurrent programming isn't really my cup of tea and I am quite new to ZIO, I would like to know if my approach is correct and if you think I am going in a good direction.
I think next steps would be to make
ManagedCacheuseSharedManagerto get a releaser and a manager factory that we would save into the cache.Here two sequences diagram to explain the idea behind my
SharedManaged