Okhttp3 source parsing (3) -Call analysis (the whole process)

### Introduction Earlier we talked about [Okhttp basic usage] (https://www.jianshu.com/p/8e404d9c160f) [Okhttp3 source parsing (1) -OkHttpClient analysis] (https://www.jianshu.com / p / bf1d01b79ce7) [Okhttp3 source parsing (2) -Request analysis] (https://www.jianshu.com/p/5a85345c8ea7) ### newCall initialization analysis ##### Call us first look at what use to the Call: `` `final Call call = okHttpClient.newCall (request);` `` Do not you remember? Either get or post request to be generated call objects, we found that in the above example needs to call a `` okHttpClient` and request` example, let's click-Call categories to see: `` `public interface Call extends Cloneable {// request request request (); // synchronization Response execute () throws IOException; // asynchronous void enqueue (Callback responseCallback); // cancellation request void cancel (); // process the request if the boolean isExecuted (); // if cancel boolean isCanceled (); Call clone (); // factory interface interface factory {Call newCall (Request request);}} `` `we found Call is the interface, and defines the some aspects of the method (method meaning on comments). We continue to look at `newCal ()` method `` `@Override public Call newCall (Request request) {return RealCall. }} `Code from the above steps that: (1)` `ensure the synchronized thread synchronization, has been performed is determined whether, if a direct Throws (2)` captureCallStackTrace (); `literally: capturing call stack traces, we found it through the source code related to the `retryAndFollowUpInterceptor` (3)` eventListener` callback `CallStart ()` (4) `client.dispatcher () executed (this);...` `dispatcher` is not seen very familiar? Before analysis `okhttpClient` initialized when it came, we click on` executed () `method to go:` `` synchronized void executed (RealCall call) {runningSyncCalls.add (call);} `` `find us passed in `realcall` put` runningSyncCalls` queue, the queue synchronous call from the literal meaning it is running, the queue is why it? : `` `Private final Deque `` Dispatcher` see is not very familiar with? Before analysis `okhttpClient` initialized when it came, we click on` executed () `method to go:` `` synchronized void executed (RealCall call) {runningSyncCalls.add (call);} `` `find us passed in `realcall` put` runningSyncCalls` queue, the queue synchronous call from the literal meaning it is running, the queue is why it? : `` `Private final Deque `` Dispatcher` see is not very familiar with? Before analysis `okhttpClient` initialized when it came, we click on` executed () `method to go:` `` synchronized void executed (RealCall call) {runningSyncCalls.add (call);} `` `find us passed in `realcall` put` runningSyncCalls` queue, the queue synchronous call from the literal meaning it is running, the queue is why it? : `` `Private final Deque runningSyncCalls = new ArrayDeque <> (); `` `> Deque i.e. deque. It is a data structure having the properties and queue stack. Deque elements can be ejected from both ends, as compared to an increase list [] Operator. . (5) We return to `execute ()` continue down analysis, the rest of the code we extract three lines of code: - `equesr result = getResponseWithInterceptorChain ();` generate a Response instance - `eventListener.callFailed (this, e); `: eventListener of callFailed callback -` client.dispatcher () finished (this); `:. finished difficult to see an example of the method dispatcher, **` getResponseWithInterceptorChain () `** in this method must ** ** core, which literally means to obtain the interceptor chain of response, which is clear, that is ** by the interceptor chain processing returns response **! [] (https://img2018.cnblogs.com/blog/1312938/ 201908 / 1312938-20190823173540636-96122427.png) ###### getResponseWithInterceptorChain () analysis `` `Response getResponseWithInterceptorChain () throws IOException {// Build a full stack of interceptors. List interceptors = new ArrayList <> (); interceptors.addAll (client.interceptors ()); // custom interceptors.add (retryAndFollowUpInterceptor); // error and tracking interceptor interceptors.add (new BridgeInterceptor (client.cookieJar () )); // bridge interceptor interceptors.add (new CacheInterceptor (client.internalCache ())); // buffer interceptor interceptors.add (new ConnectInterceptor (client));! // is connected interceptor if (forWebSocket) { interceptors.addAll (client.networkInterceptors ()); // network interceptor} interceptors.add (new CallServerInterceptor (forWebSocket)); // call to the server interceptor Interceptor.Chain chain = new RealInterceptorChain (interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis (), client.readTimeoutMillis (), client.writeTimeoutMillis ()); return chain.proceed (originalRequest);} `` `difficult to see from the above code, the first request do the layers of interception, interceptor how each of us in later chapters to talk, there will not start! It should be emphasized about the `interceptors.addAll (client. interceptors ()); `,` client.interceptors () `it is our custom interceptors in which it is defined? How do you add? We went OkHttpClient class found:! [] (Https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173540985-1903691954.png) may be added in the form of examples of `.addInterceptor` by initializing` okHttpClient`. ### asynchronous request analysis `` `call.enqueue (new Callback () {@Override public void onFailure (Call call, IOException e) {Log.d (" okhttp_error ", e.getMessage ());} @Override public void onResponse (Call call, Response response) throws IOException {Gson gson = new Gson (); Log.d ( "okhttp_success", response.body () string ().);}}); `` `click` enqueue ( ) See `:` `` @Override public void enqueue (Callback responseCallback) {synchronized (this) {if (executed) throw new IllegalStateException ( "Already Executed"); executed = true;} captureCallStackTrace (); eventListener.callStart (this ); client.dispatcher (). enqueue (new AsyncCall (responseCallback));} `` `(1) synchronized by` synchronized `guarantee thread, if judged to have been performed, if a direct Throws (2)` captureCallStackTrace (); `literally: Capture call stack trace, we found it through the source code related to the `retryAndFollowUpInterceptor` (3)` eventListener` callback `CallStart ()` (4) `client.dispatcher () enqueue (new asyncCall (responseCallback));...` call `Dispatcher.enqueue ()` and pass a ** `new asyncCall (responseCallback)` ** instance, click View ** asyncCall **: ** asyncCall is RealCall inner class! ** `` `final class AsyncCall extends NamedRunnable {private final Callback responseCallback; AsyncCall (Callback responseCallback) {super (" OkHttp% s ", redactedUrl ()); this.responseCallback = responseCallback;} String host () {return originalRequest. . url () host ();} Request request () {return originalRequest;} RealCall get () {return RealCall.this;} @Override protected void execute () {boolean signalledCallback = false; }} `` `-` runningAsyncCalls` asynchronous request queue is running - the maximum number of requests `maxRequests` 64 -` maxRequestsPerHost` host 5 requests the maximum number (may be provided by a custom Get and Set embodiment) If asynchronous running request queue size is less than 64 and the number of host requests is less than 5 will be executed (the condition) `` `runningAsyncCalls.add (call);. executorService () execute (call);` `` `asyncCall where the `` runningAsyncCalls `instance to the. `ExecutorService` continue to see the thread pool represents` executorService () `:` `` public synchronized ExecutorService executorService () {if (executorService == null) {executorService = new ThreadPoolExecutor (0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue `` `` AsyncCall herein add to `` runningAsyncCalls `in Examples. `ExecutorService` continue to see the thread pool represents` executorService () `:` `` public synchronized ExecutorService executorService () {if (executorService == null) {executorService = new ThreadPoolExecutor (0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue `` `` AsyncCall herein add to `` runningAsyncCalls `in Examples. `ExecutorService` continue to see the thread pool represents` executorService () `:` `` public synchronized ExecutorService executorService () {if (executorService == null) {executorService = new ThreadPoolExecutor (0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue (), Util.threadFactory ( "OkHttp Dispatcher", false));} return executorService;} `` `is actually generated executorService example, which understand,` AsyncCall `instances to put the thread pool! If the condition such as the number of requests above: `` `readyAsyncCalls.add (call);` `` will be added to a waiting ready asynchronous request queue, what purpose is it? ? ? Of course, waiting for an opportunity to add to runningAsyncCalls again and placed in thread pool, this logic `AsyncCall` `execute in class ()` The reason we continue to look down! ! [] (Https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173541531-1963303270.png) we have just said, if the conditions are met, `AsyncCall` instance will be in the thread pool (. start), then we go directly to run ( `execute) in ()`: `` `@Override protected void execute () {boolean signalledCallback = false; try {Response response = getResponseWithInterceptorChain (); if (retryAndFollowUpInterceptor.isCanceled ( )) {signalledCallback = true; responseCallback.onFailure (RealCall.this, new IOException ( "Canceled"));} else {signalledCallback = true; responseCallback. onResponse (RealCall.this, response);}} catch (IOException e) {if (signalledCallback) {// Do not signal the callback twice Platform.get () log (INFO, "Callback failure for" + toLoggableString ()!. , e);} else {eventListener.callFailed (RealCall.this, e); responseCallback.onFailure (RealCall.this, e);}} finally {client.dispatcher () finished (this);.}} `` `above code that is generated first through the layers of the `response` interceptor processing chain;` onResponse` and then through a series of callback `onFailure` judgment,` responseCallback`, called last `Dispatcher.finifshed ()` where ** Note that here `Dispatcher.finifshed (this)` in sync with the `Dispatcher.finifshed (this)` is not the same ** different parameters. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private }} Catch (IOException e) {if (signalledCallback) {// Do not signal the callback twice Platform.get () log (INFO, "Callback failure for" + toLoggableString (), e);!.} Else {eventListener. callFailed (RealCall.this, e); responseCallback.onFailure (RealCall.this, e);}} finally {client.dispatcher () finished (this);.}} `` `that the above code, through the first layer processing for generating the interceptor chain `response`;` onResponse` and then through a series of callback `onFailure` judgment,` responseCallback`, called last `Dispatcher.finifshed ()` It should be noted here that `** Dispatcher.finifshed (this) `and synchronization` Dispatcher.finifshed (this) `** different parameters are not the same. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private }} Catch (IOException e) {if (signalledCallback) {// Do not signal the callback twice Platform.get () log (INFO, "Callback failure for" + toLoggableString (), e);!.} Else {eventListener. callFailed (RealCall.this, e); responseCallback.onFailure (RealCall.this, e);}} finally {client.dispatcher () finished (this);.}} `` `that the above code, through the first layer processing for generating the interceptor chain `response`;` onResponse` and then through a series of callback `onFailure` judgment,` responseCallback`, called last `Dispatcher.finifshed ()` It should be noted here that `** Dispatcher.finifshed (this) `and synchronization` Dispatcher.finifshed (this) `** different parameters are not the same. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private callFailed (RealCall.this, e); responseCallback.onFailure (RealCall.this, e);}} finally {client.dispatcher () finished (this);.}} `` `that the above code, through the first layer processing for generating the interceptor chain `response`;` onResponse` and then through a series of callback `onFailure` judgment,` responseCallback`, called last `Dispatcher.finifshed ()` It should be noted here that `** Dispatcher.finifshed (this) `and synchronization` Dispatcher.finifshed (this) `** different parameters are not the same. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private callFailed (RealCall.this, e); responseCallback.onFailure (RealCall.this, e);}} finally {client.dispatcher () finished (this);.}} `` `that the above code, through the first layer processing for generating the interceptor chain `response`;` onResponse` and then through a series of callback `onFailure` judgment,` responseCallback`, called last `Dispatcher.finifshed ()` It should be noted here that `** Dispatcher.finifshed (this) `and synchronization` Dispatcher.finifshed (this) `** different parameters are not the same. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private finifshed (this) `is not the same ** different parameters. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private finifshed (this) `is not the same ** different parameters. . `` `/ ** Used by {@code AsyncCall # run} to signal completion * / void finished (AsyncCall call) {finished (runningAsyncCalls, call, true);}` `` We continue to see the specific finifshed () method : `` `private void finished(Deque calls, T call, boolean promoteCalls) { int runningCallsCount; Runnable idleCallback; synchronized (this) { if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!"); if (promoteCalls) promoteCalls(); runningCallsCount = runningCallsCount(); idleCallback = this.idleCallback; } if (runningCallsCount == 0 && idleCallback != null) { idleCallback.run(); } } ``` 在线程同步的情况下 执行了`promoteCalls();`: ``` private void promoteCalls() { if (runningAsyncCalls.size() >= maxRequests) return; // Already running max capacity. if (readyAsyncCalls.isEmpty()) return; // No ready calls to promote. for (Iterator i = readyAsyncCalls.iterator (); i.hasNext ();) {AsyncCall call = i.next (); if (runningCallsForHost (call) <maxRequestsPerHost) {i.remove (); runningAsyncCalls.add (call); executorService ( ) .execute (call);} if (runningAsyncCalls.size ()> = maxRequests) return;. // Reached max capacity}} `` `through a series of determination, the asynchronous queue of waiting ready to traverse, generate the corresponding `asyncCall` instance, and add it to runningAsyncCalls, and finally put to the thread pool! Here is the logic of how it comes above us waiting ready asynchronous queue interface with runningAsyncCalls. ##### synchronization request process ### summarized: - generating `call` Example realcall -` Dispatcher.executed () `` runningSyncCalls` added in this queue realcall - by `getResponseWithInterceptorChain ()` layers on request intercepting, generating Response -) `, the call instance is removed from the queue by` Dispatcher.finished (, returns the final response ##### asynchronous request process: - generating a `asyncCall (responseCallback)` example (implements Runnable ) - `AsyncCall` example into a` Dispatcher. enqueue () `and determine whether` maxRequests` (maximum number of requests) `maxRequestsPerHost` (the maximum number of host requests) meets the condition, if satisfied put` AsyncCall` added to `runningAsyncCalls` and placed in thread pool ; If the condition is not satisfied, it is added to the waiting queue asynchronous ready, when those conditions are satisfied is executed, in `Dispatcher.finifshed (this)` the `promoteCalls ();` method for asynchronous waits for the ready queue traversal, `asyncCall` generate the corresponding instance, and added to the `runningAsyncCalls`, and finally put to the thread pool until all requests are completed. So far OKhttp analysis on the overall process is over, the next block will be to analyze, we hope to help ...! [] (Https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173541905- 1601958458.png) I can focus my micro-channel public number: "Qin Shuai child" a quality, public attitudes numbers! ! [Public number] (https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173542046-1151555749.jpg) com / blog / 1312938/201908 / 1312938-20190823173541905-1601958458.png) I can focus my micro-channel public number: "Qin Shuai child" a quality, public attitudes numbers! ! [Public number] (https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173542046-1151555749.jpg) com / blog / 1312938/201908 / 1312938-20190823173541905-1601958458.png) I can focus my micro-channel public number: "Qin Shuai child" a quality, public attitudes numbers! ! [Public number] (https://img2018.cnblogs.com/blog/1312938/201908/1312938-20190823173542046-1151555749.jpg)

Guess you like

Origin www.cnblogs.com/qinzishuai/p/11401572.html