Skip to content

Commit

Permalink
🦄 refactor: Update signature of IJavetEngine.getGuard()
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Jun 5, 2024
1 parent 7736836 commit 8c46873
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
30 changes: 27 additions & 3 deletions docs/reference/troubleshooting/termination.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ Automatic Termination

``V8Guard`` is the built-in support for terminating a script which runs out of control.

With Engine Pool
----------------

.. code-block:: java
// Get an engine from the pool as usual.
try (IJavetEngine iJavetEngine = iJavetEnginePool.getEngine()) {
V8Runtime v8Runtime = iJavetEngine.getV8Runtime();
// Get a guard and apply try-with-resource pattern.
try (V8Guard v8Guard = v8Runtime.getGuard(10000)) {
try (V8Guard v8Guard = iJavetEngine.getGuard(10000)) {
v8Guard.setDebugModeEnabled(true);
v8Runtime.getExecutor("while (true) {}").executeVoid();
// That infinite loop will be terminated in 10 seconds by the guard.
Expand All @@ -27,6 +30,29 @@ Automatic Termination
"The V8 runtime is not dead and is still able to execute code afterwards.");
}
Please refer to the :extsource3:`source code <../../../src/test/java/com/caoccao/javet/interop/engine/TestJavetEnginePool.java>` for more detail.

Without Engine Pool
----------------

.. code-block:: java
try (V8Runtime v8Runtime = v8Host.createV8Runtime()) {
try (V8Guard v8Guard = v8Runtime.getGuard(10000)) {
v8Guard.setDebugModeEnabled(true);
assertEquals(1, v8Host.getV8GuardDaemon().getV8GuardQueue().size());
v8Runtime.getExecutor("var count = 0; while (true) { ++count; }").executeVoid();
fail("Failed to terminate execution.");
} catch (JavetException e) {
assertInstanceOf(JavetTerminatedException.class, e);
assertEquals(JavetError.ExecutionTerminated, e.getError());
assertFalse(((JavetTerminatedException) e).isContinuable());
}
assertTrue(v8Runtime.getGlobalObject().getInteger("count") > 0);
}
Please refer to the :extsource3:`source code <../../../src/test/java/com/caoccao/javet/interop/TestV8Guard.java>` for more detail.

How does ``V8Guard`` work internally? It adds itself to a priority queue held by ``V8Host`` which has a daemon thread doing the following:

* For each of the ``V8Runtime`` in the queue.
Expand All @@ -36,8 +62,6 @@ There is only one daemon thread managing all the V8 runtime instances so that th

Does ``V8Guard`` hang normal scripts till timeout is hit? No, it doesn't cause any overhead. If the script completes, ``V8Guard.close()`` will be called via try-with-resource pattern and there will be no termination.

Please refer to the :extsource3:`source code <../../../src/test/java/com/caoccao/javet/interop/engine/TestJavetEnginePool.java>` for more detail.

Manual Termination
==================

Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/caoccao/javet/interop/engine/IJavetEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package com.caoccao.javet.interop.engine;

import com.caoccao.javet.annotations.CheckReturnValue;
import com.caoccao.javet.exceptions.JavetException;
import com.caoccao.javet.interfaces.IJavetClosable;
import com.caoccao.javet.interop.V8Guard;
import com.caoccao.javet.interop.V8Runtime;

/**
Expand All @@ -35,6 +37,25 @@ public interface IJavetEngine<R extends V8Runtime> extends IJavetClosable {
*/
JavetEngineConfig getConfig();

/**
* Gets guard.
*
* @return the guard
* @since 0.7.2
*/
@CheckReturnValue
V8Guard getGuard();

/**
* Gets guard.
*
* @param timeoutMillis the timeout millis
* @return the guard
* @since 0.7.2
*/
@CheckReturnValue
V8Guard getGuard(long timeoutMillis);

/**
* Gets V8 runtime.
*
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/caoccao/javet/interop/engine/JavetEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

package com.caoccao.javet.interop.engine;

import com.caoccao.javet.annotations.CheckReturnValue;
import com.caoccao.javet.exceptions.JavetException;
import com.caoccao.javet.interop.V8Guard;
import com.caoccao.javet.interop.V8Runtime;
import com.caoccao.javet.utils.JavetDateTimeUtils;

Expand Down Expand Up @@ -104,6 +106,18 @@ public JavetEngineConfig getConfig() {
return iJavetEnginePool.getConfig();
}

@Override
@CheckReturnValue
public V8Guard getGuard() {
return getGuard(iJavetEnginePool.getConfig().getDefaultEngineGuardTimeoutMillis());
}

@Override
@CheckReturnValue
public V8Guard getGuard(long timeoutMillis) {
return v8Runtime.getGuard(timeoutMillis);
}

/**
* Gets index.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ public void testTermination() throws JavetException {
try (IJavetEngine<?> iJavetEngine = javetEnginePool.getEngine()) {
V8Runtime v8Runtime = iJavetEngine.getV8Runtime();
// Get a guard and apply try-with-resource pattern.
try (V8Guard v8Guard = v8Runtime.getGuard(3)) {
try (V8Guard v8Guard = iJavetEngine.getGuard(3)) {
v8Guard.setDebugModeEnabled(true);
v8Runtime.getExecutor("while (true) {}").executeVoid();
// That infinite loop will be terminated in 1 millisecond by the guard.
Expand All @@ -340,11 +340,10 @@ public void testTermination() throws JavetException {
public void testWithoutTermination() throws JavetException {
final long timeoutMillis = 10000;
ZonedDateTime startZonedDateTime = JavetDateTimeUtils.getUTCNow();
try (IJavetEngine<?> iJavetEngine = javetEnginePool.getEngine()) {
try (IJavetEngine<?> iJavetEngine = javetEnginePool.getEngine();
V8Guard v8Guard = iJavetEngine.getGuard(timeoutMillis)) {
V8Runtime v8Runtime = iJavetEngine.getV8Runtime();
try (V8Guard v8Guard = v8Runtime.getGuard(timeoutMillis)) {
assertEquals(2, v8Runtime.getExecutor("1 + 1").executeInteger());
}
assertEquals(2, v8Runtime.getExecutor("1 + 1").executeInteger());
}
ZonedDateTime endZonedDateTime = JavetDateTimeUtils.getUTCNow();
Duration duration = Duration.between(startZonedDateTime, endZonedDateTime);
Expand Down

0 comments on commit 8c46873

Please sign in to comment.