Java源码示例:io.undertow.server.handlers.cache.DirectBufferCache
示例1
@BeforeClass
public static void setup() throws URISyntaxException {
Path rootPath = Paths.get(RangeRequestTestCase.class.getResource("range.txt").toURI()).getParent();
PathHandler path = Handlers.path();
path.addPrefixPath("/path", new ByteRangeHandler(new HttpHandler() {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
exchange.setResponseHeader(HttpHeaderNames.LAST_MODIFIED, DateUtils.toDateString(new Date(10000)));
exchange.setResponseHeader(HttpHeaderNames.ETAG, "\"someetag\"");
exchange.setResponseContentLength("0123456789".length());
exchange.writeAsync(Unpooled.copiedBuffer("0123456789", StandardCharsets.UTF_8), true, IoCallback.END_EXCHANGE, null);
}
}, true));
path.addPrefixPath("/resource", new ResourceHandler( new PathResourceManager(rootPath, 10485760))
.setDirectoryListingEnabled(true));
path.addPrefixPath("/cachedresource", new ResourceHandler(new CachingResourceManager(1000, 1000000, new DirectBufferCache(1000, 10, 10000), new PathResourceManager(rootPath, 10485760), -1))
.setDirectoryListingEnabled(true));
path.addPrefixPath("/resource-blocking", new BlockingHandler(new ResourceHandler( new PathResourceManager(rootPath, 10485760))
.setDirectoryListingEnabled(true)));
path.addPrefixPath("/cachedresource-blocking", new BlockingHandler(new ResourceHandler(new CachingResourceManager(1000, 1000000, new DirectBufferCache(1000, 10, 10000), new PathResourceManager(rootPath, 10485760), -1))
.setDirectoryListingEnabled(true)));
DefaultServer.setRootHandler(path);
}
示例2
public CachingResourceManager(final int metadataCacheSize, final long maxFileSize, final DirectBufferCache dataCache, final ResourceManager underlyingResourceManager, final int maxAge) {
this.maxFileSize = maxFileSize;
this.underlyingResourceManager = underlyingResourceManager;
this.dataCache = dataCache;
this.cache = new LRUCache<>(metadataCacheSize, maxAge);
this.maxAge = maxAge;
if(underlyingResourceManager.isResourceChangeListenerSupported()) {
try {
underlyingResourceManager.registerResourceChangeListener(new ResourceChangeListener() {
@Override
public void handleChanges(Collection<ResourceChangeEvent> changes) {
for(ResourceChangeEvent change : changes) {
invalidate(change.getResource());
}
}
});
} catch (Exception e) {
UndertowLogger.ROOT_LOGGER.couldNotRegisterChangeListener(e);
}
}
}
示例3
@BeforeClass
public static void setup() throws ServletException {
final PathHandler root = new PathHandler();
final ServletContainer container = ServletContainer.Factory.newInstance();
DeploymentInfo builder = new DeploymentInfo()
.setClassIntrospecter(TestClassIntrospector.INSTANCE)
.setClassLoader(ServletPathMappingTestCase.class.getClassLoader())
.setContextPath("/servletContext")
.setDeploymentName("servletContext.war")
.setResourceManager(new CachingResourceManager(100, 10000,new DirectBufferCache(1000,1,1000000),new TestResourceLoader(DefaultServletCachedResourceTestCase.class), 100000));
builder.addServlet(new ServletInfo("DefaultTestServlet", PathTestServlet.class)
.addMapping("/path/default"));
builder.addServlet(new ServletInfo("default", DefaultServlet.class)
.addInitParam("directory-listing", "true")
.addMapping("/*"));
//see UNDERTOW-458
builder.addFilter(new FilterInfo("date-header", GetDateFilter.class));
builder.addFilterUrlMapping("date-header", "/*", DispatcherType.REQUEST);
builder.addFilter(new FilterInfo("Filter", HelloFilter.class));
builder.addFilterUrlMapping("Filter", "/filterpath/*", DispatcherType.REQUEST);
DeploymentManager manager = container.addDeployment(builder);
manager.deploy();
root.addPrefixPath(builder.getContextPath(), manager.start());
DefaultServer.setRootHandler(root);
}
示例4
@Override
public Long getContentLength() {
//we always use the underlying size unless the data is cached in the buffer cache
//to prevent a mis-match between size on disk and cached size
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if (dataCache == null) {
return underlyingResource.getContentLength();
}
final DirectBufferCache.CacheEntry existing = dataCache.get(cacheKey);
if (existing == null || !existing.enabled()) {
return underlyingResource.getContentLength();
}
//we only return the
return (long) existing.size();
}
示例5
public CachingResourceManager(final int metadataCacheSize, final long maxFileSize, final DirectBufferCache dataCache, final ResourceManager underlyingResourceManager, final int maxAge) {
this.maxFileSize = maxFileSize;
this.underlyingResourceManager = underlyingResourceManager;
this.dataCache = dataCache;
this.cache = new LRUCache<>(metadataCacheSize, maxAge);
this.maxAge = maxAge;
}
示例6
@Override
public Long getContentLength() {
//we always use the underlying size unless the data is cached in the buffer cache
//to prevent a mis-match between size on disk and cached size
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if(dataCache == null) {
return underlyingResource.getContentLength();
}
final DirectBufferCache.CacheEntry existing = dataCache.get(cacheKey);
if(existing == null || !existing.enabled()) {
return underlyingResource.getContentLength();
}
//we only return the
return (long)existing.size();
}
示例7
private static HttpHandler createStaticResourceHandler() {
final ResourceManager staticResources =
new ClassPathResourceManager(Server.class.getClassLoader(), "static");
// Cache tuning is copied from Undertow unit tests.
final ResourceManager cachedResources =
new CachingResourceManager(100, 65536,
new DirectBufferCache(1024, 10, 10480),
staticResources,
(int)Duration.ofDays(1).getSeconds());
final ResourceHandler resourceHandler = new ResourceHandler(cachedResources);
resourceHandler.setWelcomeFiles("index.html");
return resourceHandler;
}
示例8
public void invalidate() {
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if (dataCache != null) {
dataCache.remove(cacheKey);
}
}
示例9
@Override
public void serveRangeAsync(OutputChannel sender, HttpServerExchange exchange, long start, long end) {
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if (dataCache == null) {
((RangeAwareResource) underlyingResource).serveRangeAsync(sender, exchange, start, end);
return;
}
final DirectBufferCache.CacheEntry existing = dataCache.get(cacheKey);
final Long length = getContentLength();
//if it is not eligible to be served from the cache
if (length == null || length > cachingResourceManager.getMaxFileSize()) {
((RangeAwareResource) underlyingResource).serveRangeAsync(sender, exchange, start, end);
return;
}
//it is not cached yet, just serve it directly
if (existing == null || !existing.enabled() || !existing.reference()) {
//it is not cached yet, we can't use a range request to establish the cached item
//so we just serve it
((RangeAwareResource) underlyingResource).serveRangeAsync(sender, exchange, start, end);
} else {
//serve straight from the cache
ByteBuf[] buffers;
boolean ok = false;
try {
LimitedBufferSlicePool.PooledByteBuffer[] pooled = existing.buffers();
buffers = new ByteBuf[pooled.length];
for (int i = 0; i < buffers.length; i++) {
// Keep position from mutating
buffers[i] = pooled[i].getBuffer().duplicate();
}
ok = true;
} finally {
if (!ok) {
existing.dereference();
}
}
if (start > 0) {
long startDec = start;
long endCount = 0;
//handle the start of the range
for (ByteBuf b : buffers) {
if (endCount == end) {
b.clear();
continue;
} else if (endCount + b.readableBytes() < end) {
endCount += b.readableBytes();
} else {
b.writerIndex((int) (b.readerIndex() + (end - endCount)));
endCount = end;
}
if (b.readableBytes() >= startDec) {
startDec = 0;
b.readerIndex((int) (b.readerIndex() + startDec));
} else {
startDec -= b.readableBytes();
b.clear();
}
}
}
sender.writeAsync(Unpooled.wrappedBuffer(buffers), true, new DereferenceCallback(existing, IoCallback.END_EXCHANGE), null);
}
}
示例10
DereferenceCallback(DirectBufferCache.CacheEntry entry, final IoCallback<T> callback) {
this.entry = entry;
this.callback = callback;
}
示例11
public CachingWriteFunction(DirectBufferCache.CacheEntry cacheEntry, Long length) {
this.cacheEntry = cacheEntry;
this.length = length;
}
示例12
DirectBufferCache getDataCache() {
return dataCache;
}
示例13
public void invalidate() {
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if(dataCache != null) {
dataCache.remove(cacheKey);
}
}
示例14
@Override
public void serveRange(Sender sender, HttpServerExchange exchange, long start, long end, IoCallback completionCallback) {
final DirectBufferCache dataCache = cachingResourceManager.getDataCache();
if(dataCache == null) {
((RangeAwareResource)underlyingResource).serveRange(sender, exchange, start, end, completionCallback);
return;
}
final DirectBufferCache.CacheEntry existing = dataCache.get(cacheKey);
final Long length = getContentLength();
//if it is not eligible to be served from the cache
if (length == null || length > cachingResourceManager.getMaxFileSize()) {
underlyingResource.serve(sender, exchange, completionCallback);
return;
}
//it is not cached yet, just serve it directly
if (existing == null || !existing.enabled() || !existing.reference()) {
//it is not cached yet, install a wrapper to grab the data
((RangeAwareResource)underlyingResource).serveRange(sender, exchange, start, end, completionCallback);
} else {
//serve straight from the cache
ByteBuffer[] buffers;
boolean ok = false;
try {
LimitedBufferSlicePool.PooledByteBuffer[] pooled = existing.buffers();
buffers = new ByteBuffer[pooled.length];
for (int i = 0; i < buffers.length; i++) {
// Keep position from mutating
buffers[i] = pooled[i].getBuffer().duplicate();
}
ok = true;
} finally {
if (!ok) {
existing.dereference();
}
}
if(start > 0) {
long startDec = start;
long endCount = 0;
//handle the start of the range
for(ByteBuffer b : buffers) {
if(endCount == end) {
b.limit(b.position());
continue;
} else if(endCount + b.remaining() < end) {
endCount += b.remaining();
} else {
b.limit((int) (b.position() + (end - endCount)));
endCount = end;
}
if(b.remaining() >= startDec) {
startDec = 0;
b.position((int) (b.position() + startDec));
} else {
startDec -= b.remaining();
b.position(b.limit());
}
}
}
sender.send(buffers, new DereferenceCallback(existing, completionCallback));
}
}
示例15
DereferenceCallback(DirectBufferCache.CacheEntry entry, final IoCallback callback) {
this.entry = entry;
this.callback = callback;
}
示例16
DirectBufferCache getDataCache() {
return dataCache;
}
示例17
public static void main(String[] args) {
// https://devcenter.heroku.com/articles/dynos#local-environment-variables
LOG.info(System.getenv());
String url = System.getenv("URL");
if (url == null || url.isEmpty()) {
LOG.fatal("URL is not defined.");
return;
}
try {
URL u = new URL(url);
if (u.getProtocol().startsWith("http") == false) {
LOG.fatal("URL protocol must be http");
return;
}
} catch (IOException e) {
LOG.fatal("URL is not valid.");
return;
}
String token = System.getenv("TOKEN");
if (token == null || token.isEmpty()) {
LOG.fatal("TOKEN is not defined.");
return;
}
Set<String> tokens = new HashSet<>(Arrays.asList(token.split(",")));
String port = System.getenv("PORT");
int p = 8080;
if (port != null && Pattern.matches("\\d{1,5}", port)) {
int i = Integer.parseInt(port);
if (0 < i && i < 65536) {
p = i;
}
}
App app = new App() {
@Override
protected HttpHandler buildHandlers() {
DirectBufferCache cache = new DirectBufferCache(1024, 10, 1024 * 1024 * 200);
return new CacheHandler(cache, super.buildHandlers());
}
};
new Uml(app, url, tokens);
app.listen(p).addShutdownHook();
}