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

Add a PriorityQueue-for-idle-resources variant #88

Open
simonbasle opened this issue Jul 22, 2020 · 1 comment
Open

Add a PriorityQueue-for-idle-resources variant #88

simonbasle opened this issue Jul 22, 2020 · 1 comment
Labels
for/user-attention This issue needs user attention (feedback, rework, etc...) status/need-investigation This needs more in-depth investigation type/enhancement A general enhancement
Milestone

Comments

@simonbasle
Copy link
Member

simonbasle commented Jul 22, 2020

Motivation

An extension of #87 where other criteria than Least|Most-Recently-Used would be possible for polling order of idle resources (ie. created oldest).

The Priority Queue opens up more usages since a Comparator<PooledRef> can be used. For instance, one could prioritize youngest/oldest resources (in terms of creation time, independently of when it was last released) or by number of acquisitions. As long as the "priority" is not changing after insertion.

This implies:

  • Adding accessors for the PooledRef release timestamp (and creation timestamp): as "age" is a function of time and so is too dynamic for a priority => a timestamp is more absolute
  • Possible performance loss: the PriorityQueue interface relying on Comparator, implementations may be less efficient than simple baked-in fifo/lifo in Deque implementations

At the same time, it would better support maintaining order when polling-and-reinserting, which could help recover from some CAS failures.

Desired solution

An efficient Priority Queue implementation would be necessary, but the JDK only provides a binary-heap implementation that is not thread-safe (PriorityQueue) or a thread safe version that relies heavily on blocking/locks (PriorityBlockingQueue).

Considered alternatives

Implement one of the papers below.

Additional context

To our knowledge, no efficient lock-free implementation of Priority Queue exist in Java.
For reference, here are a few recent papers on concurrent priority queues:

@simonbasle simonbasle added type/enhancement A general enhancement for/user-attention This issue needs user attention (feedback, rework, etc...) status/need-investigation This needs more in-depth investigation labels Jul 22, 2020
@simonbasle simonbasle added this to the Backburner milestone Jul 22, 2020
@schananas
Copy link

ConcurrentSkipListSet might do the trick.

As the last paper in the list mentioned, it's possible to implement a priority queue using concurrent skip lists, and as it happens Java has lock-free skip list implementation.

I had the freedom to write a simple concurrent priority queue using Java's ConcurrentSkipListSet and it works well with one drawback:

The given structure is set, which requires all elements to have distinct priorities. This was bypassed by adding an additional comparator that compares timestamps if user-defined priorities are equal.

Additional:
In addition to mentioned use cases, I as a user would like to define my own priorities.
Use case: if the resource is in charge of processing messages (eg. Mono<Result> processMessage(Message m) ), I would like to assign priority to messages that Reactor Pool would take into consideration when choosing who will get the resource.

Example:

Mono.just(getMessage())
.flatMap(msg -> pool.withPoolable(msg.priority(), resource -> resource.processMessage(msg));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
for/user-attention This issue needs user attention (feedback, rework, etc...) status/need-investigation This needs more in-depth investigation type/enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants