-
Notifications
You must be signed in to change notification settings - Fork 5
Fix for the "compiler mirror not found" error when using dynamic execution + improvements made along the way #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
7054423
to
3abe071
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did my best to look through and things look good to me. Would probably still be good to get a second pair of eyes to review.
src/main/scala/higherkindness/rules_scala/workers/zinc/compile/ZincRunner.scala
Show resolved
Hide resolved
src/main/scala/higherkindness/rules_scala/common/worker/WorkerMain.scala
Show resolved
Hide resolved
src/main/scala/higherkindness/rules_scala/common/worker/WorkerMain.scala
Outdated
Show resolved
Hide resolved
src/main/scala/higherkindness/rules_scala/common/worker/WorkerMain.scala
Outdated
Show resolved
Hide resolved
src/main/scala/higherkindness/rules_scala/common/worker/CancellableTask.scala
Show resolved
Hide resolved
@@ -76,6 +76,10 @@ object ZincRunnerWorkerConfig { | |||
*/ | |||
object ZincRunner extends WorkerMain[ZincRunnerWorkerConfig] { | |||
|
|||
// Interrupting concurrent Zinc/Scala compilation with a shared ScalaInstance (and thus shared classloaders) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be worth elaborating here on your hypothesis for why these errors are happening.
src/main/scala/higherkindness/rules_scala/workers/common/AnnexScalaInstance.scala
Show resolved
Hide resolved
src/main/scala/higherkindness/rules_scala/workers/zinc/compile/ZincRunner.scala
Show resolved
Hide resolved
We were copying a file used by multiple threads directly to its destination. Problem is that copying is not an atomic action, so we could end up in states where the file wasn't correct when it was used. This should avoid that issue by first copying the file to a temp file and then using an atomic move to move the file to the destination used by other threads.
3f63f80
to
815b291
Compare
…s with Thread.interrupt Prior to this change there was a bug when ScalaCompile actions were used with dynamic execution. The bug would cause builds to fail with the error message "compiler mirror not found". It is my understanding this message typically indicates a problem loading the Scala Library jar during compilation. The error would always occur in the local multiplex worker's logs and not the remote logs. This commit fixes this error by not using Thread.interrupt when cancelling the future running the ScalaCompile action. My hypothesis on why this error occurs is as follows: imagine one of the classloaders in the shared ScalaInstance is in use on Thread A. That thread gets cancelled and interrupted via Thread.interrupt. This causes some kind of persistent error inside either the classloader or another part of Zinc or the Scala compiler. We correctly ignore the error on Thread A because the request it was handling was cancelled. Another thread is working a non-cancelled request, it uses that same ScalaInstance, hit that persistent error, and fails. By not using Thread.interrupt we don't trigger the persistent error and thus avoid the bug.
815b291
to
9534999
Compare
The primary problem this PR fixes is described below. I made a few other improvements along the way and included them on this PR as well.
Fix race condition in ScalaCompile by selectively interrupting futures with Thread.interrupt
Prior to this change there was a bug when ScalaCompile actions were used with dynamic execution. The bug would cause builds to fail with the error message "compiler mirror not found". It is my understanding this message typically indicates a problem loading the Scala Library jar during compilation.
The error would always occur in the local multiplex worker's logs and not the remote logs.
This commit fixes this error by not using Thread.interrupt when cancelling the future running the ScalaCompile action.
My hypothesis on why this error occurs is as follows: imagine one of the classloaders in the shared ScalaInstance is in use on Thread A. That thread gets cancelled and interrupted via Thread.interrupt. This causes some kind of persistent error inside either the classloader or another part of Zinc or the Scala compiler. We correctly ignore the error on Thread A because the request it was handling was cancelled. Another thread is working a non-cancelled request, it uses that same ScalaInstance, hit that persistent error, and fails.
By not using Thread.interrupt we don't trigger the persistent error and thus avoid the bug.