Skip to content

Commit 09cedbf

Browse files
author
Michał Wiącek
committed
stop using concurrenthash map and replace it with cats-effect Ref
There is still problem with `reflectMain` I am not sure where it is used. At the moment I have changed its signature
1 parent c76aff4 commit 09cedbf

File tree

1 file changed

+41
-29
lines changed

1 file changed

+41
-29
lines changed

frontend/src/main/scala/bloop/Cli.scala

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package bloop
33
import java.io.InputStream
44
import java.io.PrintStream
55
import java.nio.file.Path
6-
import java.util.concurrent.ConcurrentHashMap
76
import scala.util.control.NonFatal
87
import bloop.cli.CliOptions
98
import bloop.cli.Commands
@@ -23,7 +22,7 @@ import monix.eval.TaskApp
2322
import bloop.util.JavaRuntime
2423
import caseapp.core.help.Help
2524
import cats.effect.ExitCode
26-
import cats.effect.concurrent.Deferred
25+
import cats.effect.concurrent.{Deferred, Ref}
2726
import com.martiansoftware.nailgun.NGContext
2827
import monix.execution.Scheduler
2928
import 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

Comments
 (0)