Skip to content
Permalink
Browse files

Support eval

  • Loading branch information...
SpencerPark committed Jun 30, 2018
1 parent 7f5aa9a commit 3c9be900d8eb083f69395290559705d1cfcf23e1
@@ -14,7 +14,6 @@ For Maven dependency resolution, the kernel is using [ShrinkWrap resolvers](http

* [Try online](#try-online)
* [Features](#features)
* [TODO](#todo)
* [Requirements](#requirements)
* [Installing](#installing)
* [Configuring](#configuring)
@@ -45,14 +44,11 @@ Currently the kernel supports
![maven-pom-dep](docs/img/maven-pom-dep.png)
* Display rich output (See also [display.md](docs/display.md) and [maven magic](docs/magics.md#addmavendependencies)). Chart library in the demo photo is [XChart](https://github.com/knowm/XChart) with the sample code taken from their README.
![display-img](docs/img/display-img.png)
* `eval` function. **Note: the signature is `Object eval(String) throws Exception`.** This evaluates the expression (a cell) in the user scope and returns the actual evaluation result instead of a serialized one.
![eval](docs/img/eval.png)
* Configurable evaluation timeout
![timeout](docs/img/timeout.png)

#### TODO

- [ ] Support magics for making queries about the current environment.
- [ ] Compile javadocs when displaying introspection requests as html.

### Requirements

1. [Java JDK >=9](http://www.oracle.com/technetwork/java/javase/downloads/index.html). **Not the JRE**
BIN +2.53 KB docs/img/eval.png
Binary file not shown.
@@ -48,6 +48,7 @@
public static final String DEFAULT_SHELL_INIT_RESOURCE_PATH = "ijava-jshell-init.jshell";
public static final String MAGICS_INIT_RESOURCE_PATH = "ijava-magics-init.jshell";
public static final String DISPLAY_INIT_RESOURCE_PATH = "ijava-display-init.jshell";
public static final String EVAL_INIT_RESOURCE_PATH = "ijava-eval-init.jshell";

public static final String VERSION;

@@ -75,6 +75,7 @@ public JavaKernel() {
.startupScript(IJava.resource(IJava.DEFAULT_SHELL_INIT_RESOURCE_PATH))
.startupScript(IJava.resource(IJava.MAGICS_INIT_RESOURCE_PATH))
.startupScript(IJava.resource(IJava.DISPLAY_INIT_RESOURCE_PATH))
.startupScript(IJava.resource(IJava.EVAL_INIT_RESOURCE_PATH))
.startupScriptFiles(System.getenv(IJava.STARTUP_SCRIPTS_KEY))
.startupScript(System.getenv(IJava.STARTUP_SCRIPT_KEY))
.timeoutFromString(System.getenv(IJava.TIMEOUT_DURATION_KEY))
@@ -244,11 +245,15 @@ public String getBanner() {
return fmt;
}

@Override
public DisplayData eval(String expr) throws Exception {
public Object evalRaw(String expr) throws Exception {
expr = this.magicsTransformer.transformMagics(expr);

Object result = this.evaluator.eval(expr);
return this.evaluator.eval(expr);
}

@Override
public DisplayData eval(String expr) throws Exception {
Object result = this.evalRaw(expr);

if (result != null)
return result instanceof DisplayData
@@ -32,6 +32,7 @@
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
* An ExecutionControl very similar to {@link jdk.jshell.execution.LocalExecutionControl} but which
@@ -46,13 +47,13 @@

private static final Object NULL = new Object();

private static final AtomicInteger EXECUTOR_THREAD_ID = new AtomicInteger(0);

private final ExecutorService executor;

private final long timeoutTime;
private final TimeUnit timeoutUnit;

private volatile Future<Object> runningTask;

private final Map<String, Object> results = new ConcurrentHashMap<>();

public IJavaExecutionControl() {
@@ -62,7 +63,7 @@ public IJavaExecutionControl() {
public IJavaExecutionControl(long timeoutTime, TimeUnit timeoutUnit) {
this.timeoutTime = timeoutTime;
this.timeoutUnit = timeoutTime > 0 ? Objects.requireNonNull(timeoutUnit) : TimeUnit.MILLISECONDS;
this.executor = Executors.newSingleThreadExecutor((r) -> new Thread(r, "IJava-executor"));
this.executor = Executors.newCachedThreadPool(r -> new Thread(r, "IJava-executor-" + EXECUTOR_THREAD_ID.getAndIncrement()));
}

public long getTimeoutDuration() {
@@ -81,12 +82,12 @@ public Object takeResult(String key) {
}

private Object execute(Method doitMethod) throws TimeoutException, Exception {
this.runningTask = this.executor.submit(() -> doitMethod.invoke(null));
Future<Object> runningTask = this.executor.submit(() -> doitMethod.invoke(null));

try {
if (this.timeoutTime > 0)
return this.runningTask.get(this.timeoutTime, this.timeoutUnit);
return this.runningTask.get();
return runningTask.get(this.timeoutTime, this.timeoutUnit);
return runningTask.get();
} catch (CancellationException e) {
// If canceled this means that stop() was invoked in which case the protocol is to
// throw an ExecutionControl.StoppedException.
@@ -132,8 +133,7 @@ protected String invoke(Method doitMethod) throws Exception {

@Override
public void stop() throws EngineTerminationException, InternalException {
if (this.runningTask != null)
this.runningTask.cancel(true);
this.executor.shutdownNow();
}

@Override
@@ -27,6 +27,7 @@
private final String source;

public IncompleteSourceException(String source) {
super(source);
this.source = source;
}

@@ -0,0 +1,9 @@
Object eval(String expr) throws Exception {
io.github.spencerpark.ijava.JavaKernel kernel = io.github.spencerpark.ijava.IJava.getKernelInstance();

if (kernel != null) {
return kernel.evalRaw(expr);
} else {
throw new RuntimeException("No IJava kernel running");
}
}

0 comments on commit 3c9be90

Please sign in to comment.
You can’t perform that action at this time.