Является ли компилятор Scala реентерабельным?

Для многопользовательской игры по программированию я работаю над сервером фоновой компиляции для Scala, который поддерживает компиляцию нескольких независимых исходных деревьев, представленных игроками. Мне удалось запустить быструю последовательную компиляцию без перезагрузки компилятора, создав экземпляр объекта компилятора Global через

val compilerGlobal = new Global(settings, reporter)

а затем запускать отдельные задания компиляции через

val run = new compilerGlobal.Run
run.compile(sourceFilePathList)

Теперь в идеале я хотел бы распараллелить сервер (т.е. одновременно выполнить несколько компиляций), но все же без перезагрузки компилятора (в первую очередь, чтобы избежать повторного анализа библиотеки) с нуля каждый раз. Возможно ли это, т.е. является ли показанная выше вторая часть (безопасно :-) реентерабельной или она сохраняет глобальное состояние? Если нет, есть ли что-то еще, что я могу попробовать? В настоящее время я сосредоточен на поддержке Scala 2.9.1.


person Scalatron Botwar    schedule 01.04.2012    source источник
comment
Для начала он содержит «глобальное состояние» таблицы символов.   -  person user207421    schedule 01.04.2012
comment
Используйте пул экземпляров компилятора.   -  person retronym    schedule 01.04.2012
comment
@retrony Спасибо за предложение. Однако мой главный вопрос: сколько я могу переработать? Ваш комментарий предполагает, что между (в памяти) экземплярами компилятора (класс Global) нет глобального общего состояния, что является хорошим началом. Но вы также предлагаете, чтобы человек запускал общее состояние (помимо анализируемой стандартной библиотеки)? Мне нужно больше информации.   -  person Scalatron Botwar    schedule 01.04.2012
comment
Да, компилятор запускает совместное состояние, поэтому вы не должны делиться им между потоками. Это одна из проблем, возникающих в плагине Eclipse.   -  person Iulian Dragos    schedule 02.04.2012
comment
@IulianDragos Привет, Юлиан, твой ответ, кажется, окончательный, поэтому, если ты хочешь опубликовать его как ответ, я приму его, чтобы закрыть вопрос.   -  person Scalatron Botwar    schedule 07.04.2012


Ответы (1)


Да, компилятор запускает общее состояние, поэтому вы не должны делиться им между потоками. Это одна из проблем, возникающих в плагине Eclipse. Как отметил @EJP, таблица символов является общей.

Это не так важно в вашем случае, но возникает в IDE: компилятор использует ленивость в типах, что означает, что при вызове методов на Symbol могут происходить дополнительные вычисления (и мутация). Из-за проблем с видимостью важно, чтобы эти методы вызывались в том же потоке, в котором они были созданы.

person Iulian Dragos    schedule 07.04.2012