Skip to content

Commit c48aa07

Browse files
authored
Merge pull request #186 from jglick/watching-JENKINS-52165
[JENKINS-52165] Minor refinements for log push mode
2 parents 324450f + bfaf04b commit c48aa07

File tree

2 files changed

+34
-7
lines changed

2 files changed

+34
-7
lines changed

src/main/java/org/jenkinsci/plugins/durabletask/FileMonitoringTask.java

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@
7171
import java.util.logging.Logger;
7272
import edu.umd.cs.findbugs.annotations.CheckForNull;
7373
import edu.umd.cs.findbugs.annotations.NonNull;
74+
import hudson.remoting.ChannelClosedException;
75+
import java.io.EOFException;
76+
import java.nio.channels.ClosedChannelException;
77+
import java.util.stream.Stream;
7478
import jenkins.MasterToSlaveFileCallable;
7579
import jenkins.model.Jenkins;
7680
import jenkins.security.MasterToSlaveCallable;
@@ -541,8 +545,8 @@ public FilePath getOutputFile(FilePath workspace) throws IOException, Interrupte
541545
}
542546

543547
@Override public void watch(FilePath workspace, Handler handler, TaskListener listener) throws IOException, InterruptedException, ClassCastException {
544-
workspace.act(new StartWatching(this, handler, listener));
545-
LOGGER.log(Level.FINE, "started asynchronous watch in {0}", controlDir);
548+
workspace.actAsync(new StartWatching(this, handler, listener));
549+
LOGGER.log(Level.FINE, "started asynchronous watch in " + controlDir, new Throwable());
546550
}
547551

548552
/**
@@ -576,6 +580,21 @@ private static class StartWatching extends MasterToSlaveFileCallable<Void> {
576580

577581
}
578582

583+
// TODO https://github.com/jenkinsci/remoting/pull/657
584+
private static boolean isClosedChannelException(Throwable t) {
585+
if (t instanceof ClosedChannelException) {
586+
return true;
587+
} else if (t instanceof ChannelClosedException) {
588+
return true;
589+
} else if (t instanceof EOFException) {
590+
return true;
591+
} else if (t == null) {
592+
return false;
593+
} else {
594+
return isClosedChannelException(t.getCause()) || Stream.of(t.getSuppressed()).anyMatch(FileMonitoringTask::isClosedChannelException);
595+
}
596+
}
597+
579598
private static class Watcher implements Runnable {
580599

581600
private final FileMonitoringController controller;
@@ -585,6 +604,7 @@ private static class Watcher implements Runnable {
585604
private final @CheckForNull Charset cs;
586605

587606
Watcher(FileMonitoringController controller, FilePath workspace, Handler handler, TaskListener listener) {
607+
LOGGER.log(Level.FINE, "starting " + this, new Throwable());
588608
this.controller = controller;
589609
this.workspace = workspace;
590610
this.handler = handler;
@@ -611,7 +631,8 @@ private static class Watcher implements Runnable {
611631
handler.output(utf8EncodedStream);
612632
long newLocation = ch.position();
613633
lastLocationFile.write(Long.toString(newLocation), null);
614-
LOGGER.log(Level.FINER, "copied {0} bytes from {1}", new Object[] {newLocation - lastLocation, logFile});
634+
long delta = newLocation - lastLocation;
635+
LOGGER.finer(() -> this + " copied " + delta + " bytes from " + logFile);
615636
}
616637
}
617638
if (exitStatus != null) {
@@ -621,7 +642,7 @@ private static class Watcher implements Runnable {
621642
} else {
622643
output = null;
623644
}
624-
LOGGER.log(Level.FINE, "exiting with code {0}", exitStatus);
645+
LOGGER.fine(() -> this + " exiting with code " + exitStatus);
625646
handler.exited(exitStatus, output);
626647
controller.cleanup(workspace);
627648
} else {
@@ -636,7 +657,11 @@ private static class Watcher implements Runnable {
636657
}
637658
} catch (Exception x) {
638659
// note that LOGGER here is going to the agent log, not master log
639-
LOGGER.log(Level.WARNING, "giving up on watching " + controller.controlDir, x);
660+
if (isClosedChannelException(x)) {
661+
LOGGER.warning(() -> this + " giving up on watching " + controller.controlDir);
662+
} else {
663+
LOGGER.log(Level.WARNING, this + " giving up on watching " + controller.controlDir, x);
664+
}
640665
// Typically this will have been inside Handler.output, e.g.:
641666
// hudson.remoting.ChannelClosedException: channel is already closed
642667
// at hudson.remoting.Channel.send(Channel.java:667)

src/main/java/org/jenkinsci/plugins/durabletask/Handler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
import java.io.Serializable;
3232
import edu.umd.cs.findbugs.annotations.NonNull;
3333
import edu.umd.cs.findbugs.annotations.Nullable;
34+
import hudson.remoting.Asynchronous;
35+
import org.jenkinsci.remoting.SerializableOnlyOverRemoting;
3436

3537
/**
3638
* A remote handler which may be sent to an agent and handle process output and results.
3739
* If it needs to communicate with the master, you may use {@link VirtualChannel#export}.
3840
* @see Controller#watch
3941
*/
40-
public abstract class Handler implements Serializable { // TODO 2.107+ SerializableOnlyOverRemoting
42+
public abstract class Handler implements SerializableOnlyOverRemoting {
4143

4244
/**
4345
* Notification that new process output is available.
@@ -60,8 +62,8 @@ public abstract class Handler implements Serializable { // TODO 2.107+ Serializa
6062
* you still need to occasionally poll for an exit status from the master.
6163
* @param code the exit code, if known (0 conventionally represents success); may be negative for anomalous conditions such as a missing process
6264
* @param output standard output captured, if {@link DurableTask#captureOutput} was called; else null
63-
* @throws Exception if anything goes wrong, this watch is deactivated
6465
*/
66+
@Asynchronous
6567
public abstract void exited(int code, @Nullable byte[] output) throws Exception;
6668

6769
}

0 commit comments

Comments
 (0)