How to prioritize a certain request in java?
This may be a workaround, as it must be executed before the requests are sent. Taking into account your use case (500 requests at sec), my suggestion is to send first the most critical ones, by using a PriorityQueue
.
As you already batch the messages in order to send them, this approach would help into ordering the batched messages in base of the set priority.
You could first wrap the requests into another entity that holds a priority
field. For example, an skeleton/base PriorityRequest
class:
public class PriorityRequest implements Comparable<PriorityRequest>
{
public int priority;
public PriorityRequest(int priority)
{
this.priority=priority;
}
@Override
public int compareTo(PriorityRequest request)
{
return Integer.compare(request.priority,this.priority);
}
}
And declare both children, HttpPost
and HttpGet
:
public class PriorityHttpPost extends PriorityRequest
{
public HttpPost post;
public PriorityHttpPost(int priority, HttpPost post)
{
super(priority);
this.post=post;
}
}
public class PriorityHttpGet extends PriorityRequest
{
public HttpGet get;
public PriorityHttpGet(int priority, HttpGet get)
{
super(priority);
this.get=get;
}
}
So, while you create the requests, you could insert them into the queue so they get automatically located in base of their priority:
Queue<PriorityRequest> requestQueue = new PriorityQueue<>();
/*into the batch mechanism*/
requestQueue.add(new PriorityHttpPost(6,httpPost));
//...
requestQueue.add(new PriorityHttpGet(99,httpGet));
//...
This way, you guarantee the requests with higher priority to leave the queue before the lesser priority ones, as they will be ordered in descending order.
Queue- | Get (99) | --> out
| Get (9) |
| Post (6) |
| Get (3) |
| Post (1) |
Queue- | Get (9) | --> out
| Post (6) |
| Get (3) |
| Post (1) |
(...)
Just to finish, a little extra feature of this approach (in certain use cases) would consist of being able to define which elements go first and which go last:
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE, httpPostMax));
requestQueue.add(new PriorityHttpPost(INTEGER.MAX_VALUE-1, httpPostVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE+1, httpPostNotVery));
requestQueue.add(new PriorityHttpPost(INTEGER.MIN_VALUE, httpPostNoOneCares));
--
perfect world, yeah, i know..
Queue- | Post (MAX) | --> out
| Post (MAX-1) |
| ............ |
| ............ |
| Post (MIN+1) |
| Post (MIN) |
Ideally, you never want to do that on the client. You want this on the server, but I do understand that this might not be an option.
(Not going to mention HTTP/2
and priority
since I already did in the comments).
The easiest way to think about it is: "I'll just sort them based on some XXX rule". You will then realize you need a Queue/Deque
implementation, most probably a thread-safe one. You will want to put entries in this queue by some threads, but remove them by others. Thus you will need a thread-safe PriorityQueue
. And, afaik, there are only blocking implementations of such, which means - you can end-up artificially delaying non-priority requests for no reason. It gets funner, you have 100 PUT requests and only one has a HIGH
priority. You have already received the requests, but since you have no control on how threads are scheduled (the ones that insert into this queue
), your HIGH
priority request is put last.
What we did is slightly different. We get all requests and dispatch them to two different thread pools, based on their paths.
.../abc -> place in queueA -> process by thread-pool-A
.../def -> place in queueB -> process by thread-pool-B
thread-pool-A
uses threads with Thread.MIN_PRIORITY
and thread-pool-B
uses Thread.MAX_PRIORITY
. For that to sort of work, you need to read this, rather carefully. I wish I could tell you that this worked smoothly or that I have actual numbers from real production - but I have longed moved to a different workplace since then.
This is just to give you an idea that there is yet another way to do it.