![JAR search and dependency download from the Maven repository](/logo.png)
oracle.kv.impl.util.KVThreadFactory Maven / Gradle / Ivy
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.impl.util;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import oracle.kv.impl.security.ExecutionContext;
/**
* KVStore threads should have these characteristics:
* - have a descriptive name that identifies it as a KVStore owned thread
* - run as a daemon
* - have an uncaught exception handler. By default, uncaught exceptions should
* log the exception into their local log.
*/
public class KVThreadFactory implements ThreadFactory {
/* Factory name */
private final String name;
/* Used for logging uncaught exceptions. */
private final Logger logger;
private final AtomicInteger id;
/**
* @param name factory name, returned by getName()
* @param exceptionLogger should be attached to a handler that is always
* available to record uncaught exceptions. For example, it should at least
* be able to preserve the uncaught exception in the kvstore component's
* log file.
*/
public KVThreadFactory(String name, Logger exceptionLogger) {
this.name = name;
this.logger = exceptionLogger;
this.id = new AtomicInteger();
}
/**
* Name of thread. All KVThreadFactory and subclasses prefix the
* thread name with "KV". Other uses may want to override this method to
* provide more specific names, such as KVMonitorCollector. Subclasses
* need only specify the suffix, such as "MonitorCollector" in this
* method.
*/
public String getName() {
return name;
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "KV" + getName() + "_" +
id.incrementAndGet());
t.setDaemon(true);
t.setUncaughtExceptionHandler(makeUncaughtExceptionHandler());
return t;
}
/**
* By default, these threads log uncaught exceptions. Can be overwritten
* to provide different handling.
*/
public Thread.UncaughtExceptionHandler makeUncaughtExceptionHandler() {
return new LogUncaughtException();
}
private class LogUncaughtException
implements Thread.UncaughtExceptionHandler {
/**
* TODO: this method hard codes the logger level. Is that okay, or is
* more flexibility needed?
*/
@Override
public void uncaughtException(Thread t, Throwable e) {
if (logger != null) {
logger.severe(t + " experienced this uncaught exception " + e);
}
}
}
/**
* Thread factory that wraps the running of a task with an execution
* context to facilitate any security check in KVStore security system.
*/
public static class KVPrivilegedThreadFactory extends KVThreadFactory {
private final ExecutionContext execCtx;
public KVPrivilegedThreadFactory(String name,
ExecutionContext execCtx,
Logger exceptionLogger) {
super(name, exceptionLogger);
this.execCtx = execCtx;
}
@Override
public Thread newThread(final Runnable r) {
return super.newThread(new Runnable() {
@Override
public void run() {
if (execCtx == null) {
r.run();
} else {
ExecutionContext.runWithContext(
new ExecutionContext.SimpleProcedure() {
@Override
public void run() {
r.run();
}
}, execCtx);
}
}
});
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy