Previousy, even when the update report was found in the in-memory cache,
some IO was still incurred because of the coursierArtifacts key, which
was evaluated in all cases. This PR makes sure it is not evaluated when
the update report is found in cache.
FileInfo is used to wrap information like last modified time on
files that may or may not exist. Arguably, that does not make
much sense: the non-existent files should not lead to modification
file information, hashes, and a persistent serialized version of
the resulting meaningless information. However, considering that
the FileInfo information is serialized and saved, it is necessary
to preserve compatibility at this stage. Therefore the modification
time is explicitly set to zero for those files that do not exist
when each FileInfo is built.
Although in theory the fix in #3776 should be preferable to
synchronize templateStats() manually, it turns out that we
still get errors in some tests. So, reverting to a
synchronized section while we investigate.
This reverts commit ee90917cc4.
Currently the server will try to start even if there are existing sbt sessions. This causes the second session to take over the server for Unix domain socket.
This adds a check before the server comes up and make sure that the socket is not taken.
I noticed that my custom WatchService was never cleaned up by sbt and
realized that after every build we were making a new WatchService. At
the same time, we were reusing the WatchState from the previous run,
which was using the original WatchService. This was particularly
problematic because it prevented us from registering any paths with the
new watch service. This may have prevented some of the file updates
from being seen by the watch service. Moreover, because we lost the
reference to the original WatchService, there was no way to clean it up,
which was a resource leak.
May be related to #3775, #3695
Fixes#3786
To configure the log level of the server, this introduces a new task key named `serverLog`. The idea is to set this using `Global / serverLog / logLevel`. It will also check the global log level, and if all else fails, fallback to Warn.
```
lazy val level: Level.Value = (s get serverLogLevel) orElse (s get logLevel) match {
case Some(x) => x
case None => Level.Warn
}
```
`NGUnixDomainSocket` throws `java.io.IOException` instead of `SocketException`, probably because `SocketException` does not expose the contructor with a `Throwable` parameter.
To allow clients to disconnect, we need to catch `IOException`.