@@ -3,7 +3,6 @@ package bloop
33import java .io .InputStream
44import java .io .PrintStream
55import java .nio .file .Path
6- import java .util .concurrent .ConcurrentHashMap
76import scala .util .control .NonFatal
87import bloop .cli .CliOptions
98import bloop .cli .Commands
@@ -23,7 +22,7 @@ import monix.eval.TaskApp
2322import bloop .util .JavaRuntime
2423import caseapp .core .help .Help
2524import cats .effect .ExitCode
26- import cats .effect .concurrent .Deferred
25+ import cats .effect .concurrent .{ Deferred , Ref }
2726import com .martiansoftware .nailgun .NGContext
2827import monix .execution .Scheduler
2928import monix .execution .atomic .AtomicBoolean
@@ -47,7 +46,8 @@ object Cli extends TaskApp {
4746 out : PrintStream ,
4847 err : PrintStream ,
4948 props : java.util.Properties ,
50- cancel : Deferred [MonixTask , Boolean ]
49+ cancel : Deferred [MonixTask , Boolean ],
50+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]]
5151 ): MonixTask [Int ] = {
5252 val env = CommonOptions .PrettyProperties .from(props)
5353 val nailgunOptions = CommonOptions (
@@ -61,7 +61,7 @@ object Cli extends TaskApp {
6161 )
6262
6363 val cmd = parse(args, nailgunOptions)
64- val exitStatus = run(cmd, NoPool , cancel)
64+ val exitStatus = run(cmd, NoPool , cancel, activeCliSessions )
6565 exitStatus.map(_.code)
6666 }
6767
@@ -305,11 +305,11 @@ object Cli extends TaskApp {
305305 }
306306
307307 def run (action : Action , pool : ClientPool ): MonixTask [ExitStatus ] = {
308-
309308 for {
310309 baseCancellation <- Deferred [MonixTask , Boolean ]
310+ activeCliSessions <- Ref .of[MonixTask , Map [Path , List [CliSession ]]](Map .empty)
311311 _ <- baseCancellation.complete(false )
312- result <- run(action, pool, baseCancellation)
312+ result <- run(action, pool, baseCancellation, activeCliSessions )
313313 } yield result
314314 }
315315
@@ -318,7 +318,8 @@ object Cli extends TaskApp {
318318 private def run (
319319 action : Action ,
320320 pool : ClientPool ,
321- cancel : Deferred [MonixTask , Boolean ]
321+ cancel : Deferred [MonixTask , Boolean ],
322+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]]
322323 ): MonixTask [ExitStatus ] = {
323324 import bloop .io .AbsolutePath
324325 def getConfigDir (cliOptions : CliOptions ): AbsolutePath = {
@@ -360,6 +361,7 @@ object Cli extends TaskApp {
360361 action,
361362 pool,
362363 cancel,
364+ activeCliSessions,
363365 configDirectory,
364366 cliOptions,
365367 commonOpts,
@@ -372,6 +374,7 @@ object Cli extends TaskApp {
372374 action : Action ,
373375 pool : ClientPool ,
374376 cancel : Deferred [MonixTask , Boolean ],
377+ activeCliSessions : Ref [MonixTask , Map [Path , List [CliSession ]]],
375378 configDirectory : AbsolutePath ,
376379 cliOptions : CliOptions ,
377380 commonOpts : CommonOptions ,
@@ -397,27 +400,34 @@ object Cli extends TaskApp {
397400 interpret.toMonixTask(ExecutionContext .scheduler)
398401 }
399402
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+ )
401411 val exitSession = MonixTask .defer {
402- cleanUpNonStableCliDirectories(session .client)
412+ session.flatMap(s => cleanUpNonStableCliDirectories(s .client) )
403413 }
404414
405- session.task
415+ session
416+ .flatMap(_.task)
406417 .doOnCancel(exitSession)
407418 .doOnFinish(_ => exitSession)
408419 }
409420 }
410421
411- private val activeCliSessions = new ConcurrentHashMap [Path , List [CliSession ]]()
412-
413422 case class CliSession (client : CliClientInfo , task : MonixTask [ExitStatus ])
414423 def runTaskWithCliClient (
415424 configDir : AbsolutePath ,
416425 action : Action ,
417426 processCliTask : CliClientInfo => MonixTask [State ],
427+ activeCliSessions2 : Ref [MonixTask , Map [Path , List [CliSession ]]],
418428 pool : ClientPool ,
419429 logger : Logger
420- ): CliSession = {
430+ ): MonixTask [ CliSession ] = {
421431 val isClientConnected = AtomicBoolean (true )
422432 pool.addListener(_ => isClientConnected.set(false ))
423433 val defaultClient = CliClientInfo (useStableCliDirs = true , () => isClientConnected.get)
@@ -429,28 +439,30 @@ object Cli extends TaskApp {
429439
430440 val defaultClientSession = sessionFor(defaultClient)
431441 action match {
432- case Exit (_) => defaultClientSession
442+ case Exit (_) => MonixTask .now( defaultClientSession)
433443 // 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 {
445457 logger.debug(" Detected connected cli clients, starting CLI with unique dirs..." )
446458 val newClient = CliClientInfo (useStableCliDirs = false , () => isClientConnected.get)
447459 val newClientSession = sessionFor(newClient)
448- newClientSession :: sessions
460+ newClientSession :: currentSessions
449461 }
450- }
451- )
452462
453- activeSessions.head
463+ val updatedMap = sessionsMap.updated(configDir.underlying, updatedSessions)
464+ (updatedMap, updatedSessions.head)
465+ }
454466 }
455467 }
456468
0 commit comments