@@ -2,36 +2,28 @@ package bloop
2
2
3
3
import java .net .InetAddress
4
4
5
- import bloop .logging .BloopLogger
6
- import bloop .logging .Logger
5
+ import bloop .logging .{BloopLogger , Logger }
7
6
import bloop .util .ProxySetup
8
7
9
- import java .io .InputStream
10
- import java .io .PrintStream
11
- import java .nio .channels .ReadableByteChannel
12
- import java .nio .file .Files
13
- import java .nio .file .Paths
14
- import java .util .concurrent .atomic .AtomicBoolean
8
+ import java .io .{File , InputStream , OutputStream , PrintStream }
9
+ import java .net .{ServerSocket , Socket , SocketAddress }
10
+ import java .nio .ByteBuffer
11
+ import java .nio .channels .{Channels , ReadableByteChannel , SeekableByteChannel }
12
+ import java .nio .file .attribute .PosixFilePermissions
13
+ import java .nio .file .{Files , Path , Paths , StandardOpenOption }
14
+ import java .util .concurrent .atomic .{AtomicBoolean , AtomicInteger }
15
+ import java .util .concurrent .{Executors , ThreadFactory , TimeUnit }
15
16
16
- import com .martiansoftware .nailgun .NGListeningAddress
17
- import com .martiansoftware .nailgun .NGConstants
17
+ import com .martiansoftware .nailgun .{NGConstants , NGListeningAddress }
18
18
import com .martiansoftware .nailgun .{Alias , NGContext , NGServer }
19
19
import libdaemonjvm ._
20
20
import libdaemonjvm .internal .{LockProcess , SocketHandler }
21
21
import libdaemonjvm .server ._
22
22
23
- import scala .util .Properties
24
- import scala .util .Try
25
- import java .net .ServerSocket
26
- import java .net .Socket
27
- import java .io .OutputStream
28
- import java .net .SocketAddress
29
- import java .nio .channels .Channels
30
- import java .nio .ByteBuffer
31
- import java .io .File
23
+ import scala .concurrent .duration .DurationInt
24
+ import scala .util .{Properties , Try }
25
+
32
26
import org .slf4j
33
- import java .nio .file .attribute .PosixFilePermissions
34
- import java .nio .file .Path
35
27
import sun .misc .{Signal , SignalHandler }
36
28
37
29
sealed abstract class Bloop
@@ -68,8 +60,18 @@ object Bloop {
68
60
)
69
61
}
70
62
71
- if (java.lang.Boolean .getBoolean(" bloop.ignore-sig-int" ))
63
+ val pid = ProcessHandle .current().pid()
64
+ System .err.println(s " Bloop server PID: $pid" )
65
+
66
+ if (java.lang.Boolean .getBoolean(" bloop.ignore-sig-int" )) {
67
+ System .err.println(" Ignoring SIGINT" )
72
68
ignoreSigint()
69
+ }
70
+
71
+ for (value <- sys.props.get(" bloop.truncate-output-file-periodically" )) {
72
+ System .err.println(s " Will truncate output file $value every 5 minutes " )
73
+ truncateFilePeriodically(Paths .get(value))
74
+ }
73
75
74
76
lockFilesOrHostPort match {
75
77
case Left (hostPort) =>
@@ -94,6 +96,63 @@ object Bloop {
94
96
()
95
97
}
96
98
99
+ private def truncateFilePeriodically (file : Path ): Unit = {
100
+ val scheduler = Executors .newSingleThreadScheduledExecutor(
101
+ new ThreadFactory {
102
+ val count = new AtomicInteger
103
+ def newThread (r : Runnable ): Thread = {
104
+ val t = new Thread (r, s " truncate-file- ${count.incrementAndGet()}" )
105
+ t.setDaemon(true )
106
+ t
107
+ }
108
+ }
109
+ )
110
+ val period = 5 .minutes
111
+ val maxSize = 1024 * 1024 // 1 MiB
112
+ val runnable : Runnable =
113
+ () =>
114
+ try {
115
+ if (Files .exists(file)) {
116
+ val size = Files .size(file)
117
+ if (size > maxSize) {
118
+ var bc : SeekableByteChannel = null
119
+ try {
120
+ bc = Files .newByteChannel(file, StandardOpenOption .WRITE )
121
+ bc.truncate(0L )
122
+ } finally {
123
+ if (bc != null )
124
+ bc.close()
125
+ }
126
+
127
+ // Seems closing / re-opening the output file is needed for truncation to work
128
+ val ps = new PrintStream (Files .newOutputStream(file))
129
+ val formerOut = System .out
130
+ val formerErr = System .err
131
+ System .setOut(ps)
132
+ System .setErr(ps)
133
+ formerOut.close()
134
+ formerErr.close()
135
+
136
+ System .err.println(s " Truncated $file (former size: $size B) " )
137
+ ()
138
+ }
139
+ }
140
+ } catch {
141
+ case t : Throwable =>
142
+ System .err.println(
143
+ s " Caught $t while checking if $file needs to be truncated, ignoring it "
144
+ )
145
+ t.printStackTrace(System .err)
146
+ }
147
+ scheduler.scheduleAtFixedRate(
148
+ runnable,
149
+ period.length,
150
+ period.length,
151
+ period.unit
152
+ )
153
+ ()
154
+ }
155
+
97
156
def startServer (socketPathsOrHostPort : Either [(InetAddress , Int ), SocketPaths ]): Unit = {
98
157
val socketAndPathOrHostPort = socketPathsOrHostPort.map { socketPaths =>
99
158
val socket = libdaemonjvm.Util .serverSocketFromChannel(
0 commit comments