mirror of https://github.com/sbt/sbt.git
Catch ClosedChannelException in background job logger
We want the background job to stay alive even if its terminal has been closed and we cannot write to it anymore
This commit is contained in:
parent
592086b889
commit
634e8799e7
|
|
@ -126,11 +126,12 @@ object ConsoleAppender {
|
|||
def out: ConsoleOut
|
||||
}
|
||||
private[sbt] object Properties {
|
||||
def from(terminal: Terminal): Properties = new Properties {
|
||||
override def isAnsiSupported: Boolean = terminal.isAnsiSupported
|
||||
override def isColorEnabled: Boolean = terminal.isColorEnabled
|
||||
override def out = ConsoleOut.terminalOut(terminal)
|
||||
}
|
||||
def from(terminal: Terminal): Properties =
|
||||
from(ConsoleOut.terminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled)
|
||||
|
||||
def safelyFrom(terminal: Terminal): Properties =
|
||||
from(ConsoleOut.safeTerminalOut(terminal), terminal.isAnsiSupported, terminal.isColorEnabled)
|
||||
|
||||
def from(o: ConsoleOut, ansi: Boolean, color: Boolean): Properties = new Properties {
|
||||
override def isAnsiSupported: Boolean = ansi
|
||||
override def isColorEnabled: Boolean = color
|
||||
|
|
@ -246,6 +247,18 @@ object ConsoleAppender {
|
|||
new ConsoleAppender(name, Properties.from(terminal), noSuppressedMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* A new `ConsoleAppender` identified by `name`, and that writes to `terminal`.
|
||||
* Printing to this Appender will not throw if the Terminal has been closed.
|
||||
*
|
||||
* @param name An identifier for the `ConsoleAppender`.
|
||||
* @param terminal The terminal to which this appender corresponds
|
||||
* @return A new `ConsoleAppender` that writes to `terminal`.
|
||||
*/
|
||||
def safe(name: String, terminal: Terminal): Appender = {
|
||||
new ConsoleAppender(name, Properties.safelyFrom(terminal), noSuppressedMessage)
|
||||
}
|
||||
|
||||
/**
|
||||
* A new `ConsoleAppender` identified by `name`, and that writes to `out`.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
package sbt.internal.util
|
||||
|
||||
import java.io.{ BufferedWriter, PrintStream, PrintWriter }
|
||||
import java.nio.channels.ClosedChannelException
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
|
@ -90,6 +91,26 @@ object ConsoleOut {
|
|||
override def toString: String = s"TerminalOut"
|
||||
}
|
||||
|
||||
/** Same as terminalOut but it catches and ignores the ClosedChannelException
|
||||
*/
|
||||
def safeTerminalOut(terminal: Terminal): ConsoleOut = {
|
||||
val out = terminalOut(terminal)
|
||||
new ConsoleOut {
|
||||
override val lockObject: AnyRef = terminal
|
||||
override def print(s: String): Unit = catchException(out.print(s))
|
||||
override def println(s: String): Unit = catchException(out.println(s))
|
||||
override def println(): Unit = catchException(out.println())
|
||||
override def flush(): Unit = catchException(out.flush)
|
||||
override def toString: String = s"SafeTerminalOut($terminal)"
|
||||
private def catchException(f: => Unit): Unit = {
|
||||
try f
|
||||
catch {
|
||||
case _: ClosedChannelException => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[this] val consoleOutPerTerminal = new ConcurrentHashMap[Terminal, ConsoleOut]
|
||||
def terminalOut(terminal: Terminal): ConsoleOut = consoleOutPerTerminal.get(terminal) match {
|
||||
case null =>
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ object LogManager {
|
|||
task: ScopedKey[_],
|
||||
context: LoggerContext
|
||||
): ManagedLogger = {
|
||||
val console = ConsoleAppender("bg-" + ConsoleAppender.generateName(), ITerminal.current)
|
||||
val console = ConsoleAppender.safe("bg-" + ConsoleAppender.generateName(), ITerminal.current)
|
||||
LogManager.backgroundLog(data, state, task, console, relay(()), context)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue