diff options
Diffstat (limited to 'gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java')
-rw-r--r-- | gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java index c83bcc7683..1f030de969 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java @@ -43,6 +43,7 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.nio.charset.Charset; +import java.util.Optional; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicReference; import org.apache.sshd.common.SshException; @@ -268,12 +269,12 @@ public abstract class BaseCommand implements Command { } /** - * Spawn a function into its own thread. + * Spawn a function into its own thread with the provided context. * * <p>Typically this should be invoked within {@link Command#start(Environment)}, such as: * * <pre> - * startThread(new CommandRunnable() { + * startThreadWithContext(SshScope.Context context, new CommandRunnable() { * public void run() throws Exception { * runImp(); * } @@ -285,8 +286,8 @@ public abstract class BaseCommand implements Command { * * @param thunk the runnable to execute on the thread, performing the command's logic. */ - protected void startThread(final CommandRunnable thunk) { - final TaskThunk tt = new TaskThunk(thunk); + protected void startThreadWithContext(SshScope.Context context, final CommandRunnable thunk) { + final TaskThunk tt = new TaskThunk(thunk, Optional.ofNullable(context)); if (isAdminHighPriorityCommand() && user.getCapabilities().canAdministrateServer()) { // Admin commands should not block the main work threads (there @@ -299,6 +300,28 @@ public abstract class BaseCommand implements Command { } } + /** + * Spawn a function into its own thread. + * + * <p>Typically this should be invoked within {@link Command#start(Environment)}, such as: + * + * <pre> + * startThread(new CommandRunnable() { + * public void run() throws Exception { + * runImp(); + * } + * }); + * </pre> + * + * <p>If the function throws an exception, it is translated to a simple message for the client, a + * non-zero exit code, and the stack trace is logged. + * + * @param thunk the runnable to execute on the thread, performing the command's logic. + */ + protected void startThread(final CommandRunnable thunk) { + startThreadWithContext(null, thunk); + } + private boolean isAdminHighPriorityCommand() { return getClass().getAnnotation(AdminHighPriorityCommand.class) != null; } @@ -413,18 +436,21 @@ public abstract class BaseCommand implements Command { private final class TaskThunk implements CancelableRunnable, ProjectRunnable { private final CommandRunnable thunk; + private final Context taskContext; private final String taskName; + private Project.NameKey projectName; - private TaskThunk(final CommandRunnable thunk) { + private TaskThunk(final CommandRunnable thunk, Optional<Context> oneOffContext) { this.thunk = thunk; this.taskName = getTaskName(); + this.taskContext = oneOffContext.orElse(context); } @Override public void cancel() { synchronized (this) { - final Context old = sshScope.set(context); + final Context old = sshScope.set(taskContext); try { onExit(STATUS_CANCEL); } finally { @@ -439,7 +465,7 @@ public abstract class BaseCommand implements Command { final Thread thisThread = Thread.currentThread(); final String thisName = thisThread.getName(); int rc = 0; - final Context old = sshScope.set(context); + final Context old = sshScope.set(taskContext); try { context.started = TimeUtil.nowMs(); thisThread.setName("SSH " + taskName); |