7. Cache Thread Workflow for volley Source Parsing

Posted by alivec on Sun, 09 Jun 2019 23:29:42 +0200

Summary of the article
1. volley Cache Thread Running Process
2. volley implementation decomposition steps

Attachment: Get Volley source code
Demos case source code: https://github.com/HailouWang/DemosForApi

I. CacheDispatcher threads

  • 1. There are three threads in Volley, among which Cache Dispatcher is the cache thread.

  • 2. CacheDispatcher buffer threads are designed to distribute Request requests by performing shunts in the buffer pool.
    The thread runs in a loop, and the thread raw material comes from mCacheQueue. In the main thread, requests can be added to mCacheQueue through the RequestQueue.add method.

  • 3. Workflow can be simply summarized as the following steps:

    • 1. The thread runs in a loop, and the thread material comes from mCacheQueue.
    • 2. Get data from the buffer first. If there is data in the buffer, return the data directly to the main thread.
    • 3. If the cache [does not hit data] or [cache data expires], the Request is distributed to the Network Dispatcher (network thread), which resynchronizes the data.

Annex: Flow chart


  • Volley Cache Thread Flow Chart. png

II. Realization Analysis

1. The thread runs in a loop to get the Request object

while (true) {
  try {
    // Get a request from the cache triage queue, blocking until
    // at least one is available.
    //1. hlwang: Cache Dispatcher raw material from mCacheQueue, the first step is to obtain Request
    final Request<?> request = mCacheQueue.take();
    request.addMarker("cache-queue-take");
    ... ...
  }
}

2. If the Request is cancelled by the user, no further execution is required.

// If the request has been canceled, don't bother dispatching it.
//2. hlwang: If the request has been cancelled, there is no need to continue
if (request.isCanceled()) {
    request.finish("cache-discard-canceled");
    continue;
}

3. Check the buffer first. If the data is not hit (i.e. the data does not exist), then send it to the Network thread to synchronize the data.

// Attempt to retrieve this item from cache.
//3. hlwang: If there is no data in the cache, it means that it is new data, then give it to mNetworkQueue to synchronize the new data.
Cache.Entry entry = mCache.get(request.getCacheKey());
if (entry == null) {
    request.addMarker("cache-miss");
    // Cache miss; send off to the network dispatcher.
    mNetworkQueue.put(request);
    continue;
}

4. If the cached data expires, it is still left to the Network thread to synchronize the data.

// If it is completely expired, just send it to the network.
//4. hlwang: If the cache expires, it means that the data is too old and is given to mNetworkQueue to synchronize the new data.
if (entry.isExpired()) {
    request.addMarker("cache-hit-expired");
    request.setCacheEntry(entry);
    mNetworkQueue.put(request);
    continue;
}

5. When the cached data is hit, the cached data is parsed and the Response object is constructed.

// We have a cache hit; parse its data for delivery back to the request.
//5. wanghailu: We hit a cache data (w found a cache hl during the shelf life), parsed the data and constructed the response object Response.
request.addMarker("cache-hit");
Response<?> response = request.parseNetworkResponse(
        new NetworkResponse(entry.data, entry.responseHeaders));
request.addMarker("cache-hit-parsed");

6. If the data is cached and need not be refreshed, the response data is called back to the user through Delivery.

if (!entry.refreshNeeded()) {
    // Completely unexpired cache hit. Just deliver the response.
    //6. If entry data does not need to be refreshed, use mDelivery to pass the response out
    mDelivery.postResponse(request, response);
} 

7. If the cached data needs to be updated again, the cached data will now be returned to the user, and then synchronous data requests will be initiated through the main thread.

    // Soft-expired cache hit. We can deliver the cached response,
    // but we need to also send the request to the network for
    // refreshing.
    //7. Although hit by the cache, the data is slightly out of date. We can deliver and distribute cached response data.
    //But we also need to send requests to mNetworkQueue to refresh and update.
    request.addMarker("cache-hit-refresh-needed");
    request.setCacheEntry(entry);

    // Mark the response as intermediate.
    //7.1. Update response status as media
    response.intermediate = true;

    // Post the intermediate response back to the user and have
    // the delivery then forward the request along to the network.
    //7.2. Main Thread Distribution
    mDelivery.postResponse(request, response, new Runnable() {
        @Override
        public void run() {
            try {
                mNetworkQueue.put(request);
            } catch (InterruptedException e) {
                // Not much we can do about this.
            }
        }

Topics: network github