[1.8.x] Make Keys.loggerContext and LoggerContext() public#7147
Conversation
f2896ae to
2c65325
Compare
| } | ||
| def close(): Unit = { | ||
| closed.set(true) | ||
| def close(): Unit = if (closed.compareAndSet(false, true)) { |
There was a problem hiding this comment.
Just a small enhancement to make sure close() runs only once, like in line 110 of this file.
|
One workaround might be moving |
|
Yeah, I was thinking about that. However, I am just wondering is there a reason to keep those things private? |
|
|
@eed3si9n Alright, I moved the object to the |
Starting with sbt 1.8.0-RC1 a
LoggerContextwill set its internalclosedstatus totrue:sbt/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala
Lines 184 to 188 in f974cd3
The line
closed.set(true)was introduced in #6992.Because this
AtomicBooleanis true now, it of course is not possible to re use a LoggerContext anymore:sbt/internal/util-logging/src/main/scala/sbt/util/LoggerContext.scala
Lines 142 to 149 in ec77066
So far so good, this seems correct.
However this is causing problems with the Play Framework, which now runs into that exception with sbt 1.8, see playframework/playframework#11527
So basically Play has a special
NonBlockingInteractionModewhich causes an app to continue to run in the background when callingrunin a sbt console. That means, whenrunis "finished", there is still a (server) thread running that can serve requests. We use that for scripted tests. It's actually the same mechanism that sbt'sbgRunis using, only thatNonBlockingInteractionModewas implemented long time beforebgRunwas introduced in sbt 1.0.Until sbt 1.7.x this was working fine, even though the background thread was using a state's loggercontext that, in theory, was closed already, but wasn't marked as closed (even thought the close method ran).
To test things out, I also came up with a clean room
bgRunimplementation in Play, that resembled what theNonBlockingInteractionModeis doing and I was running in the exact same exception. ThatbgRunlooked somehow like this:The problem is that the body of
runInBackground, which at some point may callsProject.runTask, is not running in thebgRunlifetime anymore, but in a background thread, so after thebgRuntask finishes the loggercontext gets closed.Project.runTask(...)however tries to access the loggercontext of the passedstatewhich of course is closed now.I tried a lot to workaround that or to come up with another solution. However the only solution that I found and IMHO think is the only one to be able to resolve that (right now) is to "wrap"
Project.runTask(...)calls with an open loggercontext, which needs to be attached to thestate. To do that, I need to be able toLoggerContext- but theapplymethod is private right nowstatewithstate.put(Keys.loggerContext,..). - butKeys.loggerContextis private right nowUsing this patch here I was able to make both, Play's
NonBlockingInteractionModeand sbt'sbgRun, work in Play.These lines of playframework/playframework#11441 create a loggercontext and closes it afterwards. I also finally was able to implement
bgRunin Play in the last commit of that PR.@eed3si9n If there is nothing that speaks against opening up this key and method I would be happy if you can merge this, I will provide PRs for the
1.9.xanddevelopbranch afterwards.