@@ -3,7 +3,6 @@ package bloop
3
3
import java .io .InputStream
4
4
import java .io .PrintStream
5
5
import java .nio .file .Path
6
- import java .util .concurrent .ConcurrentHashMap
7
6
import scala .util .control .NonFatal
8
7
import bloop .cli .CliOptions
9
8
import bloop .cli .Commands
@@ -23,7 +22,7 @@ import monix.eval.TaskApp
23
22
import bloop .util .JavaRuntime
24
23
import caseapp .core .help .Help
25
24
import cats .effect .ExitCode
26
- import cats .effect .concurrent .Deferred
25
+ import cats .effect .concurrent .{ Deferred , Ref }
27
26
import com .martiansoftware .nailgun .NGContext
28
27
import monix .execution .Scheduler
29
28
import monix .execution .atomic .AtomicBoolean
@@ -47,7 +46,8 @@ object Cli extends TaskApp {
47
46
out : PrintStream ,
48
47
err : PrintStream ,
49
48
props : java.util.Properties ,
50
- cancel : Deferred [MonixTask , Boolean ]
49
+ cancel : Deferred [MonixTask , Boolean ],
50
+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]]
51
51
): MonixTask [Int ] = {
52
52
val env = CommonOptions .PrettyProperties .from(props)
53
53
val nailgunOptions = CommonOptions (
@@ -61,7 +61,7 @@ object Cli extends TaskApp {
61
61
)
62
62
63
63
val cmd = parse(args, nailgunOptions)
64
- val exitStatus = run(cmd, NoPool , cancel)
64
+ val exitStatus = run(cmd, NoPool , cancel, activeCliSessions )
65
65
exitStatus.map(_.code)
66
66
}
67
67
@@ -305,11 +305,11 @@ object Cli extends TaskApp {
305
305
}
306
306
307
307
def run (action : Action , pool : ClientPool ): MonixTask [ExitStatus ] = {
308
-
309
308
for {
310
309
baseCancellation <- Deferred [MonixTask , Boolean ]
310
+ activeCliSessions <- Ref .of[MonixTask , Map [Path , List [CliSession ]]](Map .empty)
311
311
_ <- baseCancellation.complete(false )
312
- result <- run(action, pool, baseCancellation)
312
+ result <- run(action, pool, baseCancellation, activeCliSessions )
313
313
} yield result
314
314
}
315
315
@@ -318,7 +318,8 @@ object Cli extends TaskApp {
318
318
private def run (
319
319
action : Action ,
320
320
pool : ClientPool ,
321
- cancel : Deferred [MonixTask , Boolean ]
321
+ cancel : Deferred [MonixTask , Boolean ],
322
+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]]
322
323
): MonixTask [ExitStatus ] = {
323
324
import bloop .io .AbsolutePath
324
325
def getConfigDir (cliOptions : CliOptions ): AbsolutePath = {
@@ -360,6 +361,7 @@ object Cli extends TaskApp {
360
361
action,
361
362
pool,
362
363
cancel,
364
+ activeCliSessions,
363
365
configDirectory,
364
366
cliOptions,
365
367
commonOpts,
@@ -372,6 +374,7 @@ object Cli extends TaskApp {
372
374
action : Action ,
373
375
pool : ClientPool ,
374
376
cancel : Deferred [MonixTask , Boolean ],
377
+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]],
375
378
configDirectory : AbsolutePath ,
376
379
cliOptions : CliOptions ,
377
380
commonOpts : CommonOptions ,
@@ -397,27 +400,34 @@ object Cli extends TaskApp {
397
400
interpret.toMonixTask(ExecutionContext .scheduler)
398
401
}
399
402
400
- val session = runTaskWithCliClient(configDirectory, action, taskToInterpret, pool, logger)
403
+ val session = runTaskWithCliClient(
404
+ configDirectory,
405
+ action,
406
+ taskToInterpret,
407
+ activeCliSessions,
408
+ pool,
409
+ logger
410
+ )
401
411
val exitSession = MonixTask .defer {
402
- cleanUpNonStableCliDirectories(session .client)
412
+ session.flatMap(s => cleanUpNonStableCliDirectories(s .client) )
403
413
}
404
414
405
- session.task
415
+ session
416
+ .flatMap(_.task)
406
417
.doOnCancel(exitSession)
407
418
.doOnFinish(_ => exitSession)
408
419
}
409
420
}
410
421
411
- private val activeCliSessions = new ConcurrentHashMap [Path , List [CliSession ]]()
412
-
413
422
case class CliSession (client : CliClientInfo , task : MonixTask [ExitStatus ])
414
423
def runTaskWithCliClient (
415
424
configDir : AbsolutePath ,
416
425
action : Action ,
417
426
processCliTask : CliClientInfo => MonixTask [State ],
427
+ activeCliSessions2 : Ref [MonixTask , Map [Path , List [CliSession ]]],
418
428
pool : ClientPool ,
419
429
logger : Logger
420
- ): CliSession = {
430
+ ): MonixTask [ CliSession ] = {
421
431
val isClientConnected = AtomicBoolean (true )
422
432
pool.addListener(_ => isClientConnected.set(false ))
423
433
val defaultClient = CliClientInfo (useStableCliDirs = true , () => isClientConnected.get)
@@ -429,28 +439,30 @@ object Cli extends TaskApp {
429
439
430
440
val defaultClientSession = sessionFor(defaultClient)
431
441
action match {
432
- case Exit (_) => defaultClientSession
442
+ case Exit (_) => MonixTask .now( defaultClientSession)
433
443
// Don't synchronize on commands that don't use compilation products and can run concurrently
434
- case Run (_ : Commands .About , _) => defaultClientSession
435
- case Run (_ : Commands .Projects , _) => defaultClientSession
436
- case Run (_ : Commands .Autocomplete , _) => defaultClientSession
437
- case Run (_ : Commands .Bsp , _) => defaultClientSession
438
- case Run (_ : Commands .ValidatedBsp , _) => defaultClientSession
439
- case _ =>
440
- val activeSessions = activeCliSessions.compute(
441
- configDir.underlying,
442
- (_ : Path , sessions : List [CliSession ]) => {
443
- if (sessions == null || sessions.isEmpty) List (defaultClientSession)
444
- else {
444
+ case Run (_ : Commands .About , _) => MonixTask .now(defaultClientSession)
445
+ case Run (_ : Commands .Projects , _) => MonixTask .now(defaultClientSession)
446
+ case Run (_ : Commands .Autocomplete , _) => MonixTask .now(defaultClientSession)
447
+ case Run (_ : Commands .Bsp , _) => MonixTask .now(defaultClientSession)
448
+ case Run (_ : Commands .ValidatedBsp , _) => MonixTask .now(defaultClientSession)
449
+ case a @ _ =>
450
+ activeCliSessions2.modify { sessionsMap =>
451
+ val currentSessions = sessionsMap.getOrElse(configDir.underlying, Nil )
452
+
453
+ val updatedSessions =
454
+ if (currentSessions.isEmpty) {
455
+ List (defaultClientSession)
456
+ } else {
445
457
logger.debug(" Detected connected cli clients, starting CLI with unique dirs..." )
446
458
val newClient = CliClientInfo (useStableCliDirs = false , () => isClientConnected.get)
447
459
val newClientSession = sessionFor(newClient)
448
- newClientSession :: sessions
460
+ newClientSession :: currentSessions
449
461
}
450
- }
451
- )
452
462
453
- activeSessions.head
463
+ val updatedMap = sessionsMap.updated(configDir.underlying, updatedSessions)
464
+ (updatedMap, updatedSessions.head)
465
+ }
454
466
}
455
467
}
456
468
0 commit comments