Replies: 5 comments 7 replies
-
Yes, that has been bothering me for a while... although in reality as-is, the uneveness of work distribution among the execeutors usually is not too much, especially when the runtime/resource needed for each job is roughly the same. Nevertheless, the API could use some decoupling like in this idea, instead of totally relying on the mercy of the hashing algorithm for the work distribution. Hope I can start to work on this soon. Thanks for the idea and pointers!! Wish more folks were interested enough to contribute PRs but understand the use cases of this may not be that many, speically outside the field of async and messaging.... |
Beta Was this translation helpful? Give feedback.
-
Hi @ben-manes , I know it's a lot to ask but if you could take a glance at this PR when you get a chance #3 ? Specifically with a complete code overhaul per this idea, now the whole thing is only about 30 lines of real code here: https://github.com/q3769/conseq4j/blob/f3c2143c2d6dff50e09a394cce4af494a87c1bc4/src/main/java/conseq4j/Conseq.java I am specially not sure whether to use Caffeine, Guava MapMaker, or just JDK concurrent map to host the weak-valued execution queues (CompletableFutures). Wondering if Caffeine (or any kind of cache) is an overkill for this simple case, seeing that the queues/CompletableFutures are ephemeral by nature and depending on the weak reference machanism to clear out of memeory.... Any help is much appreicated. |
Beta Was this translation helpful? Give feedback.
-
MapMaker is quite old and does not support the Java 8 atomic compute methods. They are inefficiently tacked onto Guava's Cache, but have also been buggy. That's moot since Guava recommends Caffeine for caching. You can use normal The stackoverflow example did not handle error cases. If prior future fails then the dependents using You're also very much welcome to do something different or fancier. I only offered it for inspiration. I had a use-case where I needed this type of behavior for framework integration but did not want to invest much as unpopular (JCache). I had realized that small snippet did what I wanted trivially, which was neat and let me not waste more effort. You might have more imaginative ideas on where your library evolves, but I'm glad it helps your iterations towards that. |
Beta Was this translation helpful? Give feedback.
-
Ah, I see! Thanks a bunch also for the code; will study....
A couple of thoughts at the moment:
1. Do we really want to provide the API client a "Future" at all, or just a
"void" which would reduce the complexity by a lot? i.e. "void
dispatch(Object sequenceKey, Runnable task)" vs. "<T> Future<T>
dispatch(Object sequenceKey, Callalbe<T> task)", or both (and more as in
the jdk ExecutorService)? So far my real world use cases have been mostly
"void". How about what you've seen, in terms of the need?
2. If we provide the "Future" to the client, might we as well make it
Guava's "ListenableFuture", such as "<T> ListenableFuture<T> dispatch(Object
sequenceKey, Callalbe<T> task)" ?
…On Fri, Jan 21, 2022 at 10:56 PM Ben Manes ***@***.***> wrote:
Now, main thread t-m-1 does not wait on t-cf-1's 10 seconds and instead
exits right away, which immediately renders cf1 elegible for GC/evict from
the cache even though cf1 is still in the middle of running task1.
You forgot that if cf1 is running task1 then the thread has a reference
to the future, so it is not yet eligible for garbage collection. The thread
has to complete the future (as it might have dependents). When the thread
finishes then there are no more references, so it becomes eligible for
collection and the cache may sometime later evict the entry.
—
Reply to this email directly, view it on GitHub
<#2 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADSJI4DOLB42BT66T4FURL3UXI2JVANCNFSM5MGSSWNQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I have no opinion on whether to return a future or not, it is your api and design choice. 🙂 It certainly does add to a lot of implementation complexity. I figured that if I was to write the code and tests then I might as well be more complete in case that was helpful. I could imagine that some users would want the results of the computations, so its unclear. Another possible API would be to return an I prefer |
Beta Was this translation helpful? Give feedback.
-
I stumbled across your project - neat!
You might find this stackoverflow answer helpful. The idea is to decouple the task from the thread of execution, which can be trivially done using a
CompletableFuture
. This becomes a poor-man's solution to your problem, where you can prune the mapping by either using a weak valued cache or awhenComplete
callback. The asker then wrote this blog after some private emails and his own analysis.Hope that helps!
Beta Was this translation helpful? Give feedback.
All reactions