So at server end, we have extended the org.glassfish.jersey.spi.ThreadPoolExecutorProvider
for having a bounded BlockingQueue of Runnable tasks, overriding the corePoolSize and MaximumPoolSize.
When the capacity of the BlockingQueue exceeds(when there are request which can't be queued anymore), it starts rejecting the tasks(which is as good as rejecting the requests).
But we observed that there's no response getting sent to the client when the task at the server end gets rejected for above case. Initially we didn't even know if the request are getting rejected or not, but later read about java.util.concurrent.RejectedExecutionHandler
and we tried implementing a customHandler and passing it while creating an Executor (please refer the code snippet below).
I can now see that the task is rejected but not sure how to deal with sending the response to client saying that the request was rejected. If I don't then the client keeps waiting until maybe it timeouts.
do I need to configure anything at Jersey to send the proper response to client.
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
System.err.println("MANDAR_CREATED_EXECUTOR");
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new CustomHandler());
}
class CustomHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.err.println("MANDAR_REJECTED");
executor.remove(r);
executor.purge();
}
}
PS: the style we're using for implementing the Jersey layer is this
CodePudding user response:
The solution was kinda throwing the RejectedExecutionException. This is done by new ThreadPoolExecutor.AbortPolicy()
.The thing weird was that AbortPolicy being default policy, still was not triggered earlier before overriding this createExecutor method. Seems Jersey's implementation of RejectionExecutionHandler for Executor is a bit different and not using the AbortPolicy.
@Override
protected ThreadPoolExecutor createExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler){
return super.createExecutor(corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, new ThreadPoolExecutor.AbortPolicy());
}