问题
For a multi-player programming game, I'm working on a background compilation server for Scala that supports compilation of multiple, independent source trees submitted by the players. I succeeded in running fast, sequential compilations without reloading the compiler by instantiating the Global
compiler object via
val compilerGlobal = new Global(settings, reporter)
and then running individual compile jobs via
val run = new compilerGlobal.Run
run.compile(sourceFilePathList)
I would now ideally like to parallelize the server (i.e. make multiple compilation runs concurrently), but still without reloading the compiler (primarily to avoid re-parsing the lib) from scratch each time. Is this possible, i.e. is the second part shown above (safely :-) re-entrant, or does it hold global state? If not, is there something else I can try? I am currently focused on supporting Scala 2.9.1.
回答1:
Yes, compiler Runs share state, so you should not share them between threads. It's one of the issues that comes up in the Eclipse plugin. As @EJP noted, the symbol table is shared.
This is not so important in your case, but comes up in an IDE: the compiler uses laziness in types, meaning additional computation (and mutation) may happen when calling methods on Symbol
. Because of visibility issues, it's important that these methods are called on the same thread as the one that created them.
来源:https://stackoverflow.com/questions/9961967/is-the-scala-compiler-reentrant