Skip to content

Commit c78cc52

Browse files
committed
Add evaluation and runtime components
1 parent cafb30f commit c78cc52

27 files changed

Lines changed: 1421 additions & 15 deletions

‎.editorconfig‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ root = true
22

33
[*]
44
indent_size = 2
5-
indent_style = space
5+
indent_style = tab
6+
tab_width = 2
67
trim_trailing_whitespace = true
78
insert_final_newline = false
89
charset = utf-8
910
end_of_line = lf
10-
max_line_length = 80
11-
tab_width = 2
11+
max_line_length = 80

‎runtime/build.gradle‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
plugins {
2-
id 'java'
2+
id 'java'
33
}
44

55
group 'dev.jsheets'
66
version '0.1.0'
77

88
repositories {
9-
mavenCentral()
9+
mavenCentral()
1010
}
1111

1212
dependencies {
13-
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
14-
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
13+
implementation project(':protocol')
14+
implementation 'com.google.protobuf:protobuf-java-util:3.17.3'
15+
implementation 'com.google.flogger:flogger:0.6'
16+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
17+
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
1518
}
1619

1720
test {
18-
useJUnitPlatform()
21+
useJUnitPlatform()
1922
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package jsheets.runtime.evaluation;
2+
3+
import jsheets.EvaluationError;
4+
import jsheets.EvaluationResult;
5+
import jsheets.MissingSources;
6+
7+
public interface Evaluation {
8+
interface Listener {
9+
default void onError(EvaluationError error) {}
10+
default void onResult(EvaluationResult result) {}
11+
default void onMissingSources(MissingSources sources) {}
12+
default void onEnd() {}
13+
}
14+
15+
void stop();
16+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package jsheets.runtime.evaluation;
2+
3+
import jsheets.StartEvaluationRequest;
4+
5+
public interface EvaluationEngine {
6+
Evaluation start(StartEvaluationRequest request, Evaluation.Listener listener);
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package jsheets.runtime.evaluation.shell;
2+
3+
import java.io.OutputStream;
4+
import java.io.PrintStream;
5+
import java.util.function.Consumer;
6+
7+
public class CapturingOutput extends PrintStream {
8+
private final Consumer<String> receiver;
9+
10+
public CapturingOutput(Consumer<String> receiver) {
11+
super(OutputStream.nullOutputStream());
12+
this.receiver = receiver;
13+
}
14+
15+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package jsheets.runtime.evaluation.shell;
2+
3+
import com.google.common.base.MoreObjects;
4+
import jdk.jshell.JShell;
5+
import jsheets.StartEvaluationRequest;
6+
import jsheets.runtime.evaluation.Evaluation;
7+
import jsheets.runtime.evaluation.shell.environment.ExecutionEnvironment;
8+
import jsheets.source.SharedSources;
9+
10+
import java.io.OutputStream;
11+
import java.io.PrintStream;
12+
import java.time.Clock;
13+
import java.util.concurrent.atomic.AtomicReference;
14+
15+
final class ShellEvaluation implements Evaluation {
16+
private enum Stage { Initial, Starting, Evaluating, Terminated }
17+
18+
private volatile JShell shell;
19+
20+
private final SharedSources sources;
21+
private final ExecutionEnvironment environment;
22+
private final AtomicReference<Stage> stage =
23+
new AtomicReference<>(Stage.Initial);
24+
25+
ShellEvaluation(Clock clock, ExecutionEnvironment environment) {
26+
this.environment = environment;
27+
sources = SharedSources.createEmpty(clock);
28+
}
29+
30+
public void start(StartEvaluationRequest request) {
31+
shell = JShell.builder()
32+
.out(createOutputStream())
33+
.err(createErrorStream())
34+
.build();
35+
}
36+
37+
private PrintStream createOutputStream() {
38+
return new PrintStream(OutputStream.nullOutputStream());
39+
}
40+
41+
private PrintStream createErrorStream() {
42+
return new PrintStream(OutputStream.nullOutputStream());
43+
}
44+
45+
@Override
46+
public void stop() {}
47+
48+
@Override
49+
public String toString() {
50+
return MoreObjects.toStringHelper(this)
51+
.add("shell", shell)
52+
.add("sources", sources)
53+
.add("environment", environment)
54+
.add("stage", stage)
55+
.toString();
56+
}
57+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package jsheets.runtime.evaluation.shell;
2+
3+
import com.google.common.util.concurrent.ThreadFactoryBuilder;
4+
import jsheets.StartEvaluationRequest;
5+
import jsheets.runtime.evaluation.Evaluation;
6+
import jsheets.runtime.evaluation.EvaluationEngine;
7+
import jsheets.runtime.evaluation.shell.environment.ExecutionEnvironment;
8+
9+
import java.time.Clock;
10+
import java.util.Objects;
11+
import java.util.concurrent.Executor;
12+
import java.util.concurrent.Executors;
13+
14+
public final class ShellEvaluationEngine implements EvaluationEngine {
15+
private final Clock clock;
16+
private final Executor workerPool;
17+
private final ExecutionEnvironment executionEnvironment;
18+
19+
private ShellEvaluationEngine(
20+
Clock clock,
21+
Executor workerPool,
22+
ExecutionEnvironment executionEnvironment
23+
) {
24+
this.clock = clock;
25+
this.workerPool = workerPool;
26+
this.executionEnvironment = executionEnvironment;
27+
}
28+
29+
@Override
30+
public Evaluation start(StartEvaluationRequest request, Evaluation.Listener listener) {
31+
var evaluation = new ShellEvaluation(clock, executionEnvironment);
32+
workerPool.execute(() -> evaluation.start(request));
33+
return evaluation;
34+
}
35+
36+
public static Builder newBuilder() {
37+
return new Builder();
38+
}
39+
40+
public static final class Builder {
41+
private Clock clock = Clock.systemUTC();
42+
private Executor workerPool;
43+
private ExecutionEnvironment environment;
44+
45+
public Builder useClock(Clock clock) {
46+
Objects.requireNonNull(clock, "clock");
47+
this.clock = clock;
48+
return this;
49+
}
50+
51+
public Builder useWorkerPool(Executor pool) {
52+
Objects.requireNonNull(pool, "workerPool");
53+
workerPool = pool;
54+
return this;
55+
}
56+
57+
public Builder useEnvironment(ExecutionEnvironment environment) {
58+
Objects.requireNonNull(environment, "environment");
59+
this.environment = environment;
60+
return this;
61+
}
62+
63+
public EvaluationEngine create() {
64+
return new ShellEvaluationEngine(
65+
clock,
66+
selectWorkerPool(),
67+
selectEnvironment()
68+
);
69+
}
70+
71+
private ExecutionEnvironment selectEnvironment() {
72+
return Objects.requireNonNull(environment, "environment");
73+
}
74+
75+
private Executor selectWorkerPool() {
76+
return workerPool == null ? createDefaultWorkerPool() : workerPool;
77+
}
78+
79+
private Executor createDefaultWorkerPool() {
80+
return Executors.newCachedThreadPool(
81+
new ThreadFactoryBuilder()
82+
.setDaemon(true)
83+
.setNameFormat("shell-evaluation-executor-%d")
84+
.build()
85+
);
86+
}
87+
}
88+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package jsheets.runtime.evaluation.shell.environment;
2+
3+
import jdk.jshell.spi.ExecutionControl;
4+
import jdk.jshell.spi.ExecutionControlProvider;
5+
6+
public interface ExecutionEnvironment {
7+
ExecutionControlProvider control();
8+
}

0 commit comments

Comments
 (0)