Added parentId to ThreadNamingRunnable

This commit is contained in:
Trustin Lee 2010-08-25 02:31:00 +00:00
parent 3659847859
commit d68c5160ed
12 changed files with 66 additions and 43 deletions

View File

@ -196,7 +196,7 @@ class NioClientSocketPipelineSink extends AbstractChannelSink {
try { try {
bossExecutor.execute( bossExecutor.execute(
new IoWorkerRunnable(new ThreadRenamingRunnable( new IoWorkerRunnable(new ThreadRenamingRunnable(
this, "NewIO", "ClientBoss", String.valueOf(id), null))); this, "NewIO", "ClientBoss", null, String.valueOf(id), null)));
success = true; success = true;
} finally { } finally {
if (!success) { if (!success) {

View File

@ -169,7 +169,8 @@ class NioDatagramWorker implements Runnable {
try { try {
// Start the main selector loop. See run() for details. // Start the main selector loop. See run() for details.
executor.execute(new ThreadRenamingRunnable( executor.execute(new ThreadRenamingRunnable(
this, "NewIO", "DatagramWorker", bossId + "-" + id, null)); this, "NewIO", "DatagramWorker",
String.valueOf(bossId), String.valueOf(id), null));
success = true; success = true;
} finally { } finally {
if (!success) { if (!success) {

View File

@ -156,7 +156,7 @@ class NioServerSocketPipelineSink extends AbstractChannelSink {
bossExecutor.execute( bossExecutor.execute(
new IoWorkerRunnable(new ThreadRenamingRunnable( new IoWorkerRunnable(new ThreadRenamingRunnable(
new Boss(channel), new Boss(channel),
"NewIO", "ServerBoss", String.valueOf(id), "NewIO", "ServerBoss", null, String.valueOf(id),
channel.toString()))); channel.toString())));
bossStarted = true; bossStarted = true;
} catch (Throwable t) { } catch (Throwable t) {

View File

@ -112,7 +112,7 @@ class NioWorker implements Runnable {
new IoWorkerRunnable(new ThreadRenamingRunnable( new IoWorkerRunnable(new ThreadRenamingRunnable(
this, "NewIO", this, "NewIO",
server? "ServerWorker" : "ClientWorker", server? "ServerWorker" : "ClientWorker",
bossId + "-" + id, null))); String.valueOf(bossId), String.valueOf(id), null)));
success = true; success = true;
} finally { } finally {
if (!success) { if (!success) {

View File

@ -136,7 +136,7 @@ class OioClientSocketPipelineSink extends AbstractChannelSink {
new ThreadRenamingRunnable( new ThreadRenamingRunnable(
new OioWorker(channel), new OioWorker(channel),
"OldIO", "ClientWorker", "OldIO", "ClientWorker",
id + "-" + channel.getId(), String.valueOf(id), String.valueOf(channel.getId()),
channel.toString()))); channel.toString())));
workerStarted = true; workerStarted = true;
} catch (Throwable t) { } catch (Throwable t) {

View File

@ -108,7 +108,7 @@ class OioDatagramPipelineSink extends AbstractChannelSink {
new OioDatagramWorker(channel), new OioDatagramWorker(channel),
"OldIO", "OldIO",
"DatagramWorker", "DatagramWorker",
id + "-" + channel.getId(), String.valueOf(id), String.valueOf(channel.getId()),
channel.toString()))); channel.toString())));
workerStarted = true; workerStarted = true;
} catch (Throwable t) { } catch (Throwable t) {
@ -154,13 +154,13 @@ class OioDatagramPipelineSink extends AbstractChannelSink {
// Start the business. // Start the business.
workerExecutor.execute(new IoWorkerRunnable(new ThreadRenamingRunnable( workerExecutor.execute(new IoWorkerRunnable(new ThreadRenamingRunnable(
new OioDatagramWorker(channel), new OioDatagramWorker(channel),
service, category, id + "-" + channel.getId(), comment))); service, category, String.valueOf(id), String.valueOf(channel.getId()), comment)));
} else { } else {
// Worker started by bind() - just rename. // Worker started by bind() - just rename.
Thread workerThread = channel.workerThread; Thread workerThread = channel.workerThread;
if (workerThread != null) { if (workerThread != null) {
ThreadRenamingRunnable.renameThread( ThreadRenamingRunnable.renameThread(
workerThread, service, category, id + "-" + channel.getId(), comment); workerThread, service, category, String.valueOf(id), String.valueOf(channel.getId()), comment);
} }
} }

View File

@ -177,7 +177,8 @@ class OioDatagramWorker implements Runnable {
if (workerThread != null) { if (workerThread != null) {
ThreadRenamingRunnable.renameThread( ThreadRenamingRunnable.renameThread(
workerThread, "OldIO", "DatagramWorker", workerThread, "OldIO", "DatagramWorker",
((OioDatagramChannelFactory) channel.getFactory()).id + "-" + channel.getId(), String.valueOf(((OioDatagramChannelFactory) channel.getFactory()).id),
String.valueOf(channel.getId()),
channel.toString()); channel.toString());
} }

View File

@ -151,8 +151,8 @@ class OioServerSocketPipelineSink extends AbstractChannelSink {
new IoWorkerRunnable( new IoWorkerRunnable(
new ThreadRenamingRunnable( new ThreadRenamingRunnable(
new Boss(channel), new Boss(channel),
"OldIO", "ServerBoss", String.valueOf(id), "OldIO", "ServerBoss", null,
channel.toString()))); String.valueOf(id), channel.toString())));
bossStarted = true; bossStarted = true;
} catch (Throwable t) { } catch (Throwable t) {
future.setFailure(t); future.setFailure(t);
@ -218,7 +218,9 @@ class OioServerSocketPipelineSink extends AbstractChannelSink {
new IoWorkerRunnable( new IoWorkerRunnable(
new ThreadRenamingRunnable( new ThreadRenamingRunnable(
new OioWorker(acceptedChannel), new OioWorker(acceptedChannel),
"OldIO", "ServerWorker", id + "-" + acceptedChannel.getId(), "OldIO", "ServerWorker",
String.valueOf(id),
String.valueOf(acceptedChannel.getId()),
acceptedChannel.toString()))); acceptedChannel.toString())));
} catch (Exception e) { } catch (Exception e) {
logger.warn( logger.warn(

View File

@ -211,7 +211,7 @@ public class HashedWheelTimer implements Timer {
workerThread = threadFactory.newThread(new ThreadRenamingRunnable( workerThread = threadFactory.newThread(new ThreadRenamingRunnable(
worker, worker,
"HashedWheelTimer", null, "HashedWheelTimer", null, null,
String.valueOf(id.incrementAndGet()), null)); String.valueOf(id.incrementAndGet()), null));
// Misuse check // Misuse check

View File

@ -30,13 +30,13 @@ public interface ThreadNameDeterminer {
*/ */
ThreadNameDeterminer PROPOSED = new ThreadNameDeterminer() { ThreadNameDeterminer PROPOSED = new ThreadNameDeterminer() {
public String determineThreadName(String current, String service, public String determineThreadName(String current, String service,
String category, String id, String comment) throws Exception { String category, String parentId, String id, String comment) throws Exception {
String newName = String newName =
(format("", service, " ") + (format("", " ", service) +
format("", category, " ") + format("", " ", category) +
format("#", id, " ") + format("#", " ", parentId, id) +
format("(", comment, ")")).trim(); format("(", ")", comment)).trim();
if (newName.length() == 0) { if (newName.length() == 0) {
return null; return null;
} else { } else {
@ -44,12 +44,22 @@ public interface ThreadNameDeterminer {
} }
} }
private String format(String prefix, String s, String postfix) { private String format(String prefix, String postfix, String... components) {
if (s.length() == 0) { StringBuilder buf = new StringBuilder();
return ""; for (String c: components) {
} else { if (c.length() == 0) {
return prefix + s + postfix; continue;
}
buf.append(c);
buf.append(':');
} }
if (buf.length() == 0) {
return "";
}
buf.setLength(buf.length() - 1); // Remove trailing ':'
return prefix + buf + postfix;
} }
}; };
@ -59,7 +69,7 @@ public interface ThreadNameDeterminer {
*/ */
ThreadNameDeterminer CURRENT = new ThreadNameDeterminer() { ThreadNameDeterminer CURRENT = new ThreadNameDeterminer() {
public String determineThreadName(String current, String service, public String determineThreadName(String current, String service,
String category, String id, String comment) throws Exception { String category, String parentId, String id, String comment) throws Exception {
return null; return null;
} }
}; };
@ -68,9 +78,10 @@ public interface ThreadNameDeterminer {
* Overrides the thread name proposed by {@link ThreadRenamingRunnable}. * Overrides the thread name proposed by {@link ThreadRenamingRunnable}.
* *
* @param current the current thread name * @param current the current thread name
* @param service the service name (e.g. <tt>"New I/O"</tt> or <tt>"Old I/O"</tt>) * @param service the service name (e.g. <tt>"NewIO"</tt> or <tt>"OldIO"</tt>)
* @param category the category name (e.g. <tt>"server boss"</tt> or <tt>"client worker"</tt>) * @param category the category name (e.g. <tt>"ServerBoss"</tt> or <tt>"ClientWorker"</tt>)
* @param id the thread ID (e.g. <tt>"1"</tt> or <tt>"1-3"</tt>) * @param parentId the parent thread ID (e.g. <tt>"1"</tt>)
* @param id the thread ID (e.g. <tt>"3"</tt>)
* @param comment the optional comment which might help debugging * @param comment the optional comment which might help debugging
* *
* @return the actual new thread name. * @return the actual new thread name.
@ -79,5 +90,5 @@ public interface ThreadNameDeterminer {
*/ */
String determineThreadName( String determineThreadName(
String current, String current,
String service, String category, String id, String comment) throws Exception; String service, String category, String parentId, String id, String comment) throws Exception;
} }

View File

@ -42,8 +42,7 @@ public class ThreadRenamingRunnable implements Runnable {
private static final Pattern SERVICE_PATTERN = Pattern.compile("[a-zA-Z0-9]*"); private static final Pattern SERVICE_PATTERN = Pattern.compile("[a-zA-Z0-9]*");
private static final Pattern CATEGORY_PATTERN = SERVICE_PATTERN; private static final Pattern CATEGORY_PATTERN = SERVICE_PATTERN;
private static final Pattern ID_PATTERN = Pattern.compile("^[-_a-zA-Z0-9]*$"); private static final Pattern ID_PATTERN = SERVICE_PATTERN;
private static volatile ThreadNameDeterminer threadNameDeterminer = private static volatile ThreadNameDeterminer threadNameDeterminer =
ThreadNameDeterminer.PROPOSED; ThreadNameDeterminer.PROPOSED;
@ -78,16 +77,17 @@ public class ThreadRenamingRunnable implements Runnable {
* *
* @return {@code true} if and only if the thread was renamed * @return {@code true} if and only if the thread was renamed
*/ */
public static boolean renameThread(Thread thread, String service, String category, String id, String comment) { public static boolean renameThread(Thread thread, String service, String category, String parentId, String id, String comment) {
if (thread == null) { if (thread == null) {
throw new NullPointerException("thread"); throw new NullPointerException("thread");
} }
validateNameComponents(service, category, id); validateNameComponents(service, category, parentId, id);
// Normalize the parameters. // Normalize the parameters.
service = service != null? service : ""; service = service != null? service : "";
category = category != null? category : ""; category = category != null? category : "";
parentId = parentId != null? parentId : "";
id = id != null? id : ""; id = id != null? id : "";
comment = comment != null? comment : ""; comment = comment != null? comment : "";
@ -96,7 +96,7 @@ public class ThreadRenamingRunnable implements Runnable {
String newThreadName = null; String newThreadName = null;
try { try {
newThreadName = getThreadNameDeterminer().determineThreadName( newThreadName = getThreadNameDeterminer().determineThreadName(
oldThreadName, service, category, id, comment); oldThreadName, service, category, parentId, id, comment);
} catch (Throwable t) { } catch (Throwable t) {
logger.warn("Failed to determine the thread name", t); logger.warn("Failed to determine the thread name", t);
} }
@ -121,7 +121,7 @@ public class ThreadRenamingRunnable implements Runnable {
return renamed; return renamed;
} }
private static void validateNameComponents(String service, String category, String id) { private static void validateNameComponents(String service, String category, String parentId, String id) {
if (service != null && !SERVICE_PATTERN.matcher(service).matches()) { if (service != null && !SERVICE_PATTERN.matcher(service).matches()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"service: " + service + "service: " + service +
@ -134,6 +134,12 @@ public class ThreadRenamingRunnable implements Runnable {
" (expected: " + CATEGORY_PATTERN.pattern() + ')'); " (expected: " + CATEGORY_PATTERN.pattern() + ')');
} }
if (parentId != null && !ID_PATTERN.matcher(parentId).matches()) {
throw new IllegalArgumentException(
"parentId: " + parentId +
" (expected: " + ID_PATTERN.pattern() + ')');
}
if (id != null && !ID_PATTERN.matcher(id).matches()) { if (id != null && !ID_PATTERN.matcher(id).matches()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"id: " + id + "id: " + id +
@ -144,6 +150,7 @@ public class ThreadRenamingRunnable implements Runnable {
private final Runnable runnable; private final Runnable runnable;
private final String service; private final String service;
private final String category; private final String category;
private final String parentId;
private final String id; private final String id;
private final String comment; private final String comment;
@ -154,15 +161,16 @@ public class ThreadRenamingRunnable implements Runnable {
*/ */
public ThreadRenamingRunnable( public ThreadRenamingRunnable(
Runnable runnable, Runnable runnable,
String service, String category, String id, String comment) { String service, String category, String parentId, String id, String comment) {
if (runnable == null) { if (runnable == null) {
throw new NullPointerException("runnable"); throw new NullPointerException("runnable");
} }
validateNameComponents(service, category, id); validateNameComponents(service, category, parentId, id);
this.runnable = runnable; this.runnable = runnable;
this.service = service; this.service = service;
this.category = category; this.category = category;
this.parentId = parentId;
this.id = id; this.id = id;
this.comment = comment; this.comment = comment;
} }
@ -173,7 +181,7 @@ public class ThreadRenamingRunnable implements Runnable {
// Change the thread name before starting the actual runnable. // Change the thread name before starting the actual runnable.
final boolean renamed = renameThread( final boolean renamed = renameThread(
Thread.currentThread(), service, category, id, comment); Thread.currentThread(), service, category, parentId, id, comment);
// Run the actual runnable and revert the name back when it ends. // Run the actual runnable and revert the name back when it ends.
try { try {

View File

@ -34,7 +34,7 @@ public class ThreadRenamingRunnableTest {
@Test(expected = NullPointerException.class) @Test(expected = NullPointerException.class)
public void shouldNotAllowNullRunnable() throws Exception { public void shouldNotAllowNullRunnable() throws Exception {
new ThreadRenamingRunnable(null, "a", "b", "c", "d"); new ThreadRenamingRunnable(null, "a", "b", "c", "d", "e");
} }
@Test @Test
@ -46,7 +46,7 @@ public class ThreadRenamingRunnableTest {
public void run() { public void run() {
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
}, null, null, null, null)); }, null, null, null, null, null));
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
@ -60,7 +60,7 @@ public class ThreadRenamingRunnableTest {
public void run() { public void run() {
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
}, "", "", "", "")); }, "", "", "", "", ""));
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
@ -72,10 +72,10 @@ public class ThreadRenamingRunnableTest {
e.execute(new ThreadRenamingRunnable( e.execute(new ThreadRenamingRunnable(
new Runnable() { new Runnable() {
public void run() { public void run() {
assertEquals("a b #c (d)", Thread.currentThread().getName()); assertEquals("a b #c:d (e)", Thread.currentThread().getName());
assertFalse(oldThreadName.equals(Thread.currentThread().getName())); assertFalse(oldThreadName.equals(Thread.currentThread().getName()));
} }
}, "a", "b", "c", "d")); }, "a", "b", "c", "d", "e"));
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
@ -107,7 +107,7 @@ public class ThreadRenamingRunnableTest {
public void run() { public void run() {
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());
} }
}, "a", "b", "c", "d")); }, "a", "b", "c", "d", "e"));
} finally { } finally {
System.setSecurityManager(null); System.setSecurityManager(null);
assertEquals(oldThreadName, Thread.currentThread().getName()); assertEquals(oldThreadName, Thread.currentThread().getName());