All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.apptik.comm.jus.CacheDispatcher Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2015 Apptik Project
 * Copyright (C) 2014 Kalin Maldzhanski
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.apptik.comm.jus;


import java.util.concurrent.BlockingQueue;

/**
 * Provides a threadId for performing cache triage on a queue of requests.
 * 

* Requests added to the specified cache queue are resolved from cache. * Any deliverable response is posted back to the caller via a * {@link ResponseDelivery}. Cache misses and responses that require * refresh are enqueued on the specified network queue for processing * by a {@link NetworkDispatcher}. *

*/ public class CacheDispatcher extends Thread { /** * The queue of requests coming in for triage. */ protected final BlockingQueue> mCacheQueue; /** * The queue of requests going out to the network. */ protected final BlockingQueue> mNetworkQueue; /** * The cache to read from. */ protected final Cache mCache; /** * For posting responses. */ protected final ResponseDelivery mDelivery; /** * Used for telling us to die. */ protected volatile boolean mQuit = false; /** * Creates a new cache triage dispatcher threadId. You must call {@link #start()} * in order to begin processing. * * @param cacheQueue Queue of incoming requests for triage * @param networkQueue Queue to post requests that require network to * @param cache Cache interface to use for resolution * @param delivery Delivery interface to use for posting responses */ public CacheDispatcher( BlockingQueue> cacheQueue, BlockingQueue> networkQueue, Cache cache, ResponseDelivery delivery) { mCacheQueue = cacheQueue; mNetworkQueue = networkQueue; mCache = cache; mDelivery = delivery; } /** * Forces this dispatcher to quit immediately. If any requests are still in * the queue, they are not guaranteed to be processed. */ public void quit() { mQuit = true; interrupt(); } protected void setThreadPriority() { this.setPriority(Thread.NORM_PRIORITY); } @Override public void run() { //todo add queue markers setThreadPriority(); // Make a blocking call to initialize the cache. mCache.initialize(); while (true) { try { // Get a request from the cache triage queue, blocking until // at least one is available. final Request request = mCacheQueue.take(); request.addMarker(Request.EVENT_CACHE_QUEUE_TAKE); // If the request has been canceled, don't bother dispatching it. if (request.isCanceled()) { request.finish(Request.EVENT_CACHE_DISCARD_CANCELED); continue; } // Attempt to retrieve this item from cache. Cache.Entry entry = mCache.get(request.getCacheKey()); if (entry == null) { request.addMarker(Request.EVENT_CACHE_MISS); // Cache miss; send off to the network dispatcher. mNetworkQueue.put(request); continue; } // If it is completely expired, just send it to the network. if (entry.isExpired()) { request.addMarker(Request.EVENT_CACHE_HIT_EXPIRED); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. request.addMarker(Request.EVENT_CACHE_HIT); Response response = request.parseNetworkResponse( new NetworkResponse(-1, entry.data, entry.responseHeaders, 0)); request.addMarker(Request.EVENT_CACHE_HIT_PARSED); if (!entry.refreshNeeded()) { // Completely unexpired cache hit. Just deliver the response. mDelivery.postResponse(request, response); } else { // Soft-expired cache hit. We can deliver the cached response, // but we need to also send the request to the network for // refreshing. request.addMarker(Request.EVENT_CACHE_HIT_REFRESH_NEEDED); request.setCacheEntry(entry); // Mark the response as intermediate. response.intermediate = true; // Post the intermediate response back to the user and have // the delivery then forward the request along to the network. mDelivery.postResponse(request, response, new Runnable() { @Override public void run() { try { mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy