![JAR search and dependency download from the Maven repository](/logo.png)
io.apptik.comm.jus.CacheDispatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jus-java Show documentation
Show all versions of jus-java Show documentation
Communication library for Android and Java
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