mirror of https://github.com/sbt/sbt.git
Merge pull request #6001 from eatkins/evaluate-task-memory-leak
Fix EvaluateTask memory leak
This commit is contained in:
commit
f35675286b
|
|
@ -72,12 +72,15 @@ final case class State(
|
||||||
* @param currentExecId provide the execId extracted from the original State.
|
* @param currentExecId provide the execId extracted from the original State.
|
||||||
* @param combinedParser the parser extracted from the original State.
|
* @param combinedParser the parser extracted from the original State.
|
||||||
*/
|
*/
|
||||||
|
@deprecated("unused", "1.4.2")
|
||||||
private[sbt] final case class SafeState(
|
private[sbt] final case class SafeState(
|
||||||
currentExecId: Option[String],
|
currentExecId: Option[String],
|
||||||
combinedParser: Parser[() => sbt.State]
|
combinedParser: Parser[() => sbt.State]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated("unused", "1.4.2")
|
||||||
private[sbt] object SafeState {
|
private[sbt] object SafeState {
|
||||||
|
@deprecated("use StandardMain.exchange.withState", "1.4.2")
|
||||||
def apply(s: State) = {
|
def apply(s: State) = {
|
||||||
new SafeState(
|
new SafeState(
|
||||||
currentExecId = s.currentCommand.map(_.execId).flatten,
|
currentExecId = s.currentCommand.map(_.execId).flatten,
|
||||||
|
|
|
||||||
|
|
@ -413,9 +413,13 @@ object EvaluateTask {
|
||||||
(dummyRoots, roots) :: (Def.dummyStreamsManager, streams) :: (dummyState, state) :: dummies
|
(dummyRoots, roots) :: (Def.dummyStreamsManager, streams) :: (dummyState, state) :: dummies
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@deprecated("use StandardMain.exchange.withState to obtain an instance of State", "1.4.2")
|
||||||
val lastEvaluatedState: AtomicReference[SafeState] = new AtomicReference()
|
val lastEvaluatedState: AtomicReference[SafeState] = new AtomicReference()
|
||||||
|
@deprecated("use currentlyRunningTaskEngine", "1.4.2")
|
||||||
val currentlyRunningEngine: AtomicReference[(SafeState, RunningTaskEngine)] =
|
val currentlyRunningEngine: AtomicReference[(SafeState, RunningTaskEngine)] =
|
||||||
new AtomicReference()
|
new AtomicReference()
|
||||||
|
private[sbt] val currentlyRunningTaskEngine: AtomicReference[RunningTaskEngine] =
|
||||||
|
new AtomicReference()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main method for the task engine.
|
* The main method for the task engine.
|
||||||
|
|
@ -486,7 +490,7 @@ object EvaluateTask {
|
||||||
shutdownImpl(true)
|
shutdownImpl(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentlyRunningEngine.set((SafeState(state), runningEngine))
|
currentlyRunningTaskEngine.set(runningEngine)
|
||||||
// Register with our cancel handler we're about to start.
|
// Register with our cancel handler we're about to start.
|
||||||
val strat = config.cancelStrategy
|
val strat = config.cancelStrategy
|
||||||
val cancelState = strat.onTaskEngineStart(runningEngine)
|
val cancelState = strat.onTaskEngineStart(runningEngine)
|
||||||
|
|
@ -494,8 +498,7 @@ object EvaluateTask {
|
||||||
try run()
|
try run()
|
||||||
finally {
|
finally {
|
||||||
strat.onTaskEngineFinish(cancelState)
|
strat.onTaskEngineFinish(cancelState)
|
||||||
currentlyRunningEngine.set(null)
|
currentlyRunningTaskEngine.set(null)
|
||||||
lastEvaluatedState.set(SafeState(state))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -422,8 +422,7 @@ final class NetworkChannel(
|
||||||
protected def onCompletionRequest(execId: Option[String], cp: CompletionParams) = {
|
protected def onCompletionRequest(execId: Option[String], cp: CompletionParams) = {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
try {
|
try {
|
||||||
Option(EvaluateTask.lastEvaluatedState.get) match {
|
StandardMain.exchange.withState { sstate =>
|
||||||
case Some(sstate) =>
|
|
||||||
import sbt.protocol.codec.JsonProtocol._
|
import sbt.protocol.codec.JsonProtocol._
|
||||||
def completionItems(s: State) = {
|
def completionItems(s: State) = {
|
||||||
Parser
|
Parser
|
||||||
|
|
@ -435,15 +434,14 @@ final class NetworkChannel(
|
||||||
}
|
}
|
||||||
.map(c => cp.query + c)
|
.map(c => cp.query + c)
|
||||||
}
|
}
|
||||||
val (items, cachedMainClassNames, cachedTestNames) = StandardMain.exchange.withState {
|
val (items, cachedMainClassNames, cachedTestNames) = {
|
||||||
s =>
|
|
||||||
val scopedKeyParser: Parser[Seq[Def.ScopedKey[_]]] =
|
val scopedKeyParser: Parser[Seq[Def.ScopedKey[_]]] =
|
||||||
Act.aggregatedKeyParser(s) <~ Parsers.any.*
|
Act.aggregatedKeyParser(sstate) <~ Parsers.any.*
|
||||||
Parser.parse(cp.query, scopedKeyParser) match {
|
Parser.parse(cp.query, scopedKeyParser) match {
|
||||||
case Right(keys) =>
|
case Right(keys) =>
|
||||||
val testKeys =
|
val testKeys =
|
||||||
keys.filter(k => k.key.label == "testOnly" || k.key.label == "testQuick")
|
keys.filter(k => k.key.label == "testOnly" || k.key.label == "testQuick")
|
||||||
val (testState, cachedTestNames) = testKeys.foldLeft((s, true)) {
|
val (testState, cachedTestNames) = testKeys.foldLeft((sstate, true)) {
|
||||||
case ((st, allCached), k) =>
|
case ((st, allCached), k) =>
|
||||||
SessionVar.loadAndSet(sbt.Keys.definedTestNames in k.scope, st, true) match {
|
SessionVar.loadAndSet(sbt.Keys.definedTestNames in k.scope, st, true) match {
|
||||||
case (nst, d) => (nst, allCached && d.isDefined)
|
case (nst, d) => (nst, allCached && d.isDefined)
|
||||||
|
|
@ -457,7 +455,7 @@ final class NetworkChannel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(completionItems(runState), cachedMainClassNames, cachedTestNames)
|
(completionItems(runState), cachedMainClassNames, cachedTestNames)
|
||||||
case _ => (completionItems(s), true, true)
|
case _ => (completionItems(sstate), true, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
respondResult(
|
respondResult(
|
||||||
|
|
@ -468,12 +466,6 @@ final class NetworkChannel(
|
||||||
),
|
),
|
||||||
execId
|
execId
|
||||||
)
|
)
|
||||||
case _ =>
|
|
||||||
respondError(
|
|
||||||
ErrorCodes.UnknownError,
|
|
||||||
"No available sbt state",
|
|
||||||
execId
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
case NonFatal(_) =>
|
case NonFatal(_) =>
|
||||||
|
|
@ -498,9 +490,10 @@ final class NetworkChannel(
|
||||||
)
|
)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Option(EvaluateTask.currentlyRunningEngine.get) match {
|
Option(EvaluateTask.currentlyRunningTaskEngine.get) match {
|
||||||
case Some((state, runningEngine)) =>
|
case Some(runningEngine) =>
|
||||||
val runningExecId = state.currentExecId.getOrElse("")
|
val runningExecId =
|
||||||
|
StandardMain.exchange.withState(_.currentCommand.flatMap(_.execId).getOrElse(""))
|
||||||
val expected = StandardMain.exchange.withState(
|
val expected = StandardMain.exchange.withState(
|
||||||
_.get(BasicCommands.execMap)
|
_.get(BasicCommands.execMap)
|
||||||
.flatMap(s => s.get(crp.id) orElse s.get("\u2668" + crp.id))
|
.flatMap(s => s.get(crp.id) orElse s.get("\u2668" + crp.id))
|
||||||
|
|
@ -936,9 +929,10 @@ object NetworkChannel {
|
||||||
id: String
|
id: String
|
||||||
): Either[String, String] = {
|
): Either[String, String] = {
|
||||||
|
|
||||||
Option(EvaluateTask.currentlyRunningEngine.get) match {
|
Option(EvaluateTask.currentlyRunningTaskEngine.get) match {
|
||||||
case Some((state, runningEngine)) =>
|
case Some(runningEngine) =>
|
||||||
val runningExecId = state.currentExecId.getOrElse("")
|
val runningExecId =
|
||||||
|
StandardMain.exchange.withState(_.currentCommand.flatMap(_.execId).getOrElse(""))
|
||||||
|
|
||||||
def checkId(): Boolean = {
|
def checkId(): Boolean = {
|
||||||
if (runningExecId.startsWith("\u2668")) {
|
if (runningExecId.startsWith("\u2668")) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue