Goal:
Last enqueued okhttp3.Call
is executed first
Tried solution: LIFO Executor
(not work)
I have found a solution for a LIFO Executor
(Executor Service with LIFO ordering), and applied this kind of Executor
into OkHttpClient
by this way
private val httpClient = OkHttpClient.Builder().dispatcher(
Dispatcher(ThreadPoolExecutor(..., LifoLinkedBlockingDequeue<Runnable>()))
).build()
But, this didn't work.
Analysis
After tracing source code in okhttp3.Dispatcher
, I found that:
- First, every enqueued
Call
is added into(private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>())
inDispatcher.java
" - Then, those
Call
s are moved fromreadyAsyncCalls
to the blocking deque ofExecutor
in FIFO order - Finally,
Call
s inExecutor
are executed in LIFO order
In my case, tremendous Call
s are produced at the same time, and there are relatively less threads consuming them.
--> Most Call
s are queued in Dispatcher
instead of in Executor
at a moment
--> LIFO Executor
doesn't play the effect
Example
| Dispatcher: 1,2,3,4,5 | Executor: | executing: | done: |
| Dispatcher: 2,3,4,5 | Executor:1 | executing: | done: |
| Dispatcher: 4,5 | Executor:2,3 | executing:1 | done: |
| Dispatcher: 5 | Executor:4 | executing:3,2 | done:1 |
| Dispatcher: | Executor:5 | executing:4 | done:1,3,2 |
| Dispatcher: | Executor: | executing:5 | done:1,3,2,4 |
| Dispatcher: | Executor: | executing: | done:1,3,2,4,5 |
Call
s are moved fromDispatcher
toExecutor
in FIFO order, and this procedure is very "inefficient".Call
s fromExecutor
to executing state is in LIFO order. But there are fewCall
s inExecutor
, LIFO effect is not obvious.
Does anyone know other way to achieve this?
I found out that the reason why it's INEFFICIENT to move requests from
Dispatcher
toExecutor
is: there are two maximums for number of moved requests at a time.Sol
Set a greater value for
Dispatcher.maxRequests
andDispatcher.maxRequestPerHost
So that every new incoming request can be moved to executor as soon as possible
--> to give full scope to the characteristic of queue passed into
Executor
But... I'm not sure that whether large maximum will cause any side effects...