
io.jsync.impl.DefaultContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsync.io Show documentation
Show all versions of jsync.io Show documentation
jsync.io is a non-blocking, event-driven networking framework for Java
/*
* Copyright (c) 2011-2013 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*/
package io.jsync.impl;
import io.jsync.AsyncResult;
import io.jsync.AsyncResultHandler;
import io.jsync.Context;
import io.jsync.Handler;
import io.jsync.file.impl.PathResolver;
import io.jsync.logging.Logger;
import io.jsync.logging.impl.LoggerFactory;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Executor;
/**
* @author Tim Fox
*/
public abstract class DefaultContext implements Context {
private static final Logger log = LoggerFactory.getLogger(DefaultContext.class);
protected final AsyncInternal async;
protected final Executor orderedBgExec;
private final ClassLoader tccl;
private final EventLoop eventLoop;
private DeploymentHandle deploymentContext;
private PathResolver pathResolver;
private Set closeHooks;
private boolean closed;
protected DefaultContext(AsyncInternal async, Executor orderedBgExec) {
this.async = async;
this.orderedBgExec = orderedBgExec;
EventLoopGroup group = async.getEventLoopGroup();
if (group != null) {
this.eventLoop = group.next();
this.tccl = Thread.currentThread().getContextClassLoader();
} else {
this.eventLoop = null;
this.tccl = null;
}
}
public void setTCCL() {
Thread.currentThread().setContextClassLoader(tccl);
}
public DeploymentHandle getDeploymentHandle() {
return deploymentContext;
}
public void setDeploymentHandle(DeploymentHandle deploymentHandle) {
this.deploymentContext = deploymentHandle;
}
public PathResolver getPathResolver() {
return pathResolver;
}
public void setPathResolver(PathResolver pathResolver) {
this.pathResolver = pathResolver;
}
public void reportException(Throwable t) {
if (deploymentContext != null) {
deploymentContext.reportException(t);
} else {
log.error("Unhandled exception", t);
}
}
public void addCloseHook(Closeable hook) {
if (closeHooks == null) {
closeHooks = new HashSet<>();
}
closeHooks.add(hook);
}
public void removeCloseHook(Closeable hook) {
if (closeHooks != null) {
closeHooks.remove(hook);
}
}
public void runCloseHooks(Handler> doneHandler) {
if (closeHooks != null) {
final CountingCompletionHandler aggHandler = new CountingCompletionHandler<>(async, closeHooks.size());
aggHandler.setHandler(doneHandler);
// Copy to avoid ConcurrentModificationException
for (Closeable hook : new HashSet<>(closeHooks)) {
try {
hook.close(new AsyncResultHandler() {
@Override
public void handle(AsyncResult asyncResult) {
if (asyncResult.failed()) {
aggHandler.failed(asyncResult.cause());
} else {
aggHandler.complete();
}
}
});
} catch (Throwable t) {
reportException(t);
}
}
} else {
doneHandler.handle(new DefaultFutureResult<>((Void) null));
}
}
public abstract void execute(Runnable handler);
public abstract boolean isOnCorrectWorker(EventLoop worker);
public void execute(EventLoop worker, Runnable handler) {
if (isOnCorrectWorker(worker)) {
wrapTask(handler).run();
} else {
execute(handler);
}
}
public void runOnContext(final Handler task) {
execute(new Runnable() {
public void run() {
task.handle(null);
}
});
}
public EventLoop getEventLoop() {
return eventLoop;
}
// This executes the task in the worker pool using the ordered executor of the context
// It's used e.g. from BlockingActions
protected void executeOnOrderedWorkerExec(final Runnable task) {
orderedBgExec.execute(wrapTask(task));
}
public void close() {
unsetContext();
closed = true;
}
private void unsetContext() {
async.setContext(null);
}
protected Runnable wrapTask(final Runnable task) {
return new Runnable() {
public void run() {
Thread currentThread = Thread.currentThread();
String threadName = currentThread.getName();
try {
async.setContext(DefaultContext.this);
task.run();
} catch (Throwable t) {
reportException(t);
} finally {
if (!threadName.equals(currentThread.getName())) {
currentThread.setName(threadName);
}
}
if (closed) {
// We allow tasks to be run after the context is closed but we make sure we unset the context afterwards
// to avoid any leaks
unsetContext();
}
}
};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy