Skip to content

Commit 8424a53

Browse files
authored
Disable certain fsNotifyWatchLog logging to prevent indefinite loops (#5856)
Disables certain entries written to `fsNotifyWatchLog` which cause indefinite loops, CPU usage and disk trashing in watch mode. Essentially: - writing to watch log generates an event - which then gets picked up by mill - which gets written to watch log - which then generates an event Fixes #5843
1 parent f3c4db6 commit 8424a53

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

runner/daemon/src/mill/daemon/Watching.scala

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ object Watching {
127127
doWatch(notifiablesChanged = () => watchedPathsSeq.exists(p => !haveNotChanged(p)))
128128

129129
def doWatchFsNotify() = {
130-
Using.resource(os.write.outputStream(watchArgs.daemonDir / "fsNotifyWatchLog")) { watchLog =>
130+
val watchLogFile = watchArgs.daemonDir / "fsNotifyWatchLog"
131+
Using.resource(os.write.outputStream(watchLogFile)) { watchLog =>
131132
def writeToWatchLog(s: String): Unit = {
132133
try {
133134
watchLog.write(s.getBytes(java.nio.charset.StandardCharsets.UTF_8))
@@ -195,15 +196,29 @@ object Watching {
195196
changedPaths.exists(p =>
196197
watchedPathsSet.exists(watchedPath => p.startsWith(watchedPath))
197198
)
198-
writeToWatchLog(
199-
s"[changed-paths] (hasWatchedPath=$hasWatchedPath) ${changedPaths.mkString("\n")}"
200-
)
199+
200+
// Do not log if the only thing that changed was the watch log file itself.
201+
//
202+
// See https://github.com/com-lihaoyi/mill/issues/5843
203+
if (hasWatchedPath || changedPaths.exists(_ != watchLogFile)) {
204+
writeToWatchLog(
205+
s"[changed-paths] (hasWatchedPath=$hasWatchedPath) ${changedPaths.mkString("\n")}"
206+
)
207+
}
208+
201209
if (hasWatchedPath) {
202210
pathChangesDetected = true
203211
}
204212
},
205-
logger = (eventType, data) =>
206-
writeToWatchLog(s"[watch:event] $eventType: ${pprint.apply(data).plainText}")
213+
logger = (eventType, data) => {
214+
val _ = eventType
215+
val _ = data
216+
// Uncommenting this causes indefinite loop as writing to watch log triggers an event, which then
217+
// gets written to the watch log, which then triggers an event, and so on.
218+
//
219+
// https://github.com/com-lihaoyi/mill/issues/5843
220+
// writeToWatchLog(s"[watch:event] $eventType: ${pprint.apply(data).plainText}")
221+
}
207222
)) { _ =>
208223
// If already stale, re-evaluate instantly.
209224
//

0 commit comments

Comments
 (0)