Janino - время сценариев процессора и выделенные байты
Я пытаюсь построить изолированную программную среду сценариев с использованием Janino, чтобы я мог безопасно выполнять пользовательские функции, ограничивая импорт, процессорное время и выделенные байты.
В Rhino (для кода javascript) у меня есть функция с именем наблюдаем InstructionCount(Context ctx, int инструкция Count), которая вызывается каждые X инструкций, где X может быть определен пользователем при построении среды.
В этой функции я могу сделать что-то вроде этого:
/**
* This method is called every {@code instructionsBeforeObserve} and it is
* used to check if the current execution has exceded the {@code maxCpuTime}
* or the {maxMemory}. If so, an {@link java.lang.Error} is thrown.
*
*/
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
SafeContext sctx = (SafeContext) cx;
//Check CPU Time
if (getMaxCpuTime() > 0) {
long currentTime = System.currentTimeMillis();
if (currentTime - sctx.getStartTime() > getMaxCpuTime()) {
throw new Error("Max CPU Time limit of " + getMaxCpuTime() + " was exceeded");
}
}
//Check Memory Consumption
if (getMaxMemory() > 0 && threadMonitor != null) {
if (sctx.getStartMemory() <= 0) {
sctx.setStartMemory(threadMonitor.getThreadAllocatedBytes(sctx.getThreadId()));
} else {
long currentAllocatedBytes = threadMonitor.getThreadAllocatedBytes(sctx.getThreadId());
if ((currentAllocatedBytes - sctx.getStartMemory()) >= getMaxMemory()) {
throw new Error("Max Memory limit of " + getMaxMemory() + " was exceeded");
}
}
}
}
контролировать время выполнения и выделенные байты.
Даже если пользователь создает цикл (например, while(true) {}), эта функция будет в конечном счете вызвана, и если ранее определенное время выполнения было превышено, это выдаст ошибку, и выполнение сценария остановится.
Я пытаюсь воспроизвести это поведение с помощью Janino, но у меня нет аналогичного механизма для мониторинга выполнения сценариев. Если пользователь вызывает блокирующую функцию, у меня нет возможности остановить скрипт, кроме как внезапно вызвать thread.stop() в потоке, выполняющем скрипт, что может быть проблематично. Любые другие вызовы, такие как thread.interrupt() (насколько я знаю) не будут прерывать блокирующие вызовы.
Любые идеи о том, как я могу решить эту проблему?