Skip to content

Commit 6e4eae4

Browse files
committed
New Actor constructor
1 parent 9f564a4 commit 6e4eae4

File tree

19 files changed

+251
-142
lines changed

19 files changed

+251
-142
lines changed

README.md

Lines changed: 81 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -254,36 +254,36 @@ package io.eigr.spawn.java.demo;
254254

255255
import io.eigr.spawn.api.Value;
256256
import io.eigr.spawn.api.actors.ActorContext;
257-
import io.eigr.spawn.api.annotations.Action;
258-
import io.eigr.spawn.api.annotations.NamedActor;
257+
import io.eigr.spawn.api.actors.annotations.Action;
258+
import io.eigr.spawn.api.actors.annotations.NamedActor;
259259
import io.eigr.spawn.java.demo.domain.Domain;
260260
import org.slf4j.Logger;
261261
import org.slf4j.LoggerFactory;
262262

263263
@NamedActor(name = "joe", stateType = Domain.JoeState.class)
264264
public class Joe {
265-
private static final Logger log = LoggerFactory.getLogger(Joe.class);
266-
267-
@Action(name = "hi", inputType = Domain.Request.class)
268-
public Value hi(Domain.Request msg, ActorContext<Domain.JoeState> context) {
269-
log.info("Received invocation. Message: {}. Context: {}", msg, context);
270-
if (context.getState().isPresent()) {
271-
log.info("State is present and value is {}", context.getState().get());
272-
}
273-
274-
return Value.at()
275-
.response(Domain.Reply.newBuilder()
276-
.setResponse("Hello From Java")
277-
.build())
278-
.state(updateState("erlang"))
279-
.reply();
280-
}
281-
282-
private Domain.JoeState updateState(String language) {
283-
return Domain.JoeState.newBuilder()
284-
.addLanguages(language)
285-
.build();
286-
}
265+
private static final Logger log = LoggerFactory.getLogger(Joe.class);
266+
267+
@Action(name = "hi", inputType = Domain.Request.class)
268+
public Value hi(Domain.Request msg, ActorContext<Domain.JoeState> context) {
269+
log.info("Received invocation. Message: {}. Context: {}", msg, context);
270+
if (context.getState().isPresent()) {
271+
log.info("State is present and value is {}", context.getState().get());
272+
}
273+
274+
return Value.at()
275+
.response(Domain.Reply.newBuilder()
276+
.setResponse("Hello From Java")
277+
.build())
278+
.state(updateState("erlang"))
279+
.reply();
280+
}
281+
282+
private Domain.JoeState updateState(String language) {
283+
return Domain.JoeState.newBuilder()
284+
.addLanguages(language)
285+
.build();
286+
}
287287
}
288288
```
289289

@@ -293,20 +293,20 @@ to serve as your application's entrypoint and fill it with the following content
293293
```Java
294294
package io.eigr.spawn.java.demo;
295295

296-
import io.eigr.spawn.Spawn;
297-
import io.eigr.spawn.Spawn.SpawnSystem;
296+
import io.eigr.spawn.api.Spawn;
297+
import io.eigr.spawn.api.Spawn.SpawnSystem;
298298

299299
public class App {
300-
public static void main(String[] args) throws Exception {
301-
Spawn spawnSystem = new SpawnSystem()
302-
.create("spawn-system")
303-
.withPort(8091)
304-
.withProxyPort(9003)
305-
.withActor(Joe.class)
306-
.build();
307-
308-
spawnSystem.start();
309-
}
300+
public static void main(String[] args) throws Exception {
301+
Spawn spawnSystem = new SpawnSystem()
302+
.create("spawn-system")
303+
.withPort(8091)
304+
.withProxyPort(9003)
305+
.withActor(Joe.class)
306+
.build();
307+
308+
spawnSystem.start();
309+
}
310310
}
311311
```
312312

@@ -401,35 +401,35 @@ To produce events in a topic, just use the Broadcast Workflow. The example below
401401
```Java
402402
package io.eigr.spawn.java.demo;
403403

404-
import io.eigr.spawn.api.workflows.Broadcast;
404+
import io.eigr.spawn.api.actors.workflows.Broadcast;
405405
// some imports omitted for brevity
406406

407407
@NamedActor(name = "joe", stateful = true, stateType = Domain.JoeState.class, channel = "test")
408408
public class Joe {
409-
@TimerAction(name = "hi", period = 60000)
410-
public Value hi(ActorContext<Domain.JoeState> context) {
411-
Domain.Request msg = Domain.Request.newBuilder()
412-
.setLanguage("erlang")
413-
.build();
414-
415-
return Value.at()
416-
.flow(Broadcast.to("test", "setLanguage", msg))
417-
.response(Domain.Reply.newBuilder()
418-
.setResponse("Hello From Erlang")
419-
.build())
420-
.state(updateState("erlang"))
421-
.reply();
422-
}
423-
424-
@Action(inputType = Domain.Request.class)
425-
public Value setLanguage(Domain.Request msg, ActorContext<Domain.JoeState> context) {
426-
return Value.at()
427-
.response(Domain.Reply.newBuilder()
428-
.setResponse("Hello From Java")
429-
.build())
430-
.state(updateState("java"))
431-
.reply();
432-
}
409+
@TimerAction(name = "hi", period = 60000)
410+
public Value hi(ActorContext<Domain.JoeState> context) {
411+
Domain.Request msg = Domain.Request.newBuilder()
412+
.setLanguage("erlang")
413+
.build();
414+
415+
return Value.at()
416+
.flow(Broadcast.to("test", "setLanguage", msg))
417+
.response(Domain.Reply.newBuilder()
418+
.setResponse("Hello From Erlang")
419+
.build())
420+
.state(updateState("erlang"))
421+
.reply();
422+
}
423+
424+
@Action(inputType = Domain.Request.class)
425+
public Value setLanguage(Domain.Request msg, ActorContext<Domain.JoeState> context) {
426+
return Value.at()
427+
.response(Domain.Reply.newBuilder()
428+
.setResponse("Hello From Java")
429+
.build())
430+
.state(updateState("java"))
431+
.reply();
432+
}
433433
// ....
434434
}
435435
```
@@ -540,32 +540,32 @@ More detailed in complete main class:
540540
```java
541541
package io.eigr.spawn.java.demo;
542542

543-
import io.eigr.spawn.Spawn;
544-
import io.eigr.spawn.Spawn.SpawnSystem;
543+
import io.eigr.spawn.api.Spawn;
544+
import io.eigr.spawn.api.Spawn.SpawnSystem;
545545
import io.eigr.spawn.api.actors.ActorRef;
546546
import io.eigr.spawn.java.demo.domain.Domain;
547547

548548
import java.util.Optional;
549549

550550
public class App {
551-
public static void main(String[] args) throws Exception {
552-
Spawn spawnSystem = new SpawnSystem()
553-
.create("spawn-system")
554-
.withPort(8091)
555-
.withProxyPort(9003)
556-
.withActor(Joe.class)
557-
.build();
558-
559-
spawnSystem.start();
560-
561-
ActorRef joeActor = spawnSystem.createActorRef("spawn-system", "joe");
562-
563-
Domain.Request msg = Domain.Request.newBuilder()
564-
.setLanguage("erlang")
565-
.build();
566-
Domain.Reply reply =
567-
(Domain.Reply) joeActor.invoke("setLanguage", msg, Domain.Reply.class, Optional.empty());
568-
}
551+
public static void main(String[] args) throws Exception {
552+
Spawn spawnSystem = new SpawnSystem()
553+
.create("spawn-system")
554+
.withPort(8091)
555+
.withProxyPort(9003)
556+
.withActor(Joe.class)
557+
.build();
558+
559+
spawnSystem.start();
560+
561+
ActorRef joeActor = spawnSystem.createActorRef("spawn-system", "joe");
562+
563+
Domain.Request msg = Domain.Request.newBuilder()
564+
.setLanguage("erlang")
565+
.build();
566+
Domain.Reply reply =
567+
(Domain.Reply) joeActor.invoke("setLanguage", msg, Domain.Reply.class, Optional.empty());
568+
}
569569
}
570570
```
571571

src/main/java/io/eigr/spawn/Spawn.java renamed to src/main/java/io/eigr/spawn/api/Spawn.java

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
package io.eigr.spawn;
1+
package io.eigr.spawn.api;
22

33
import com.sun.net.httpserver.HttpServer;
44
import io.eigr.functions.protocol.Protocol;
55
import io.eigr.functions.protocol.actors.ActorOuterClass;
6+
import io.eigr.spawn.api.actors.ActorFactory;
67
import io.eigr.spawn.api.actors.ActorRef;
7-
import io.eigr.spawn.api.annotations.NamedActor;
8-
import io.eigr.spawn.api.annotations.PooledActor;
9-
import io.eigr.spawn.api.annotations.UnNamedActor;
8+
import io.eigr.spawn.api.actors.annotations.NamedActor;
9+
import io.eigr.spawn.api.actors.annotations.PooledActor;
10+
import io.eigr.spawn.api.actors.annotations.UnNamedActor;
1011
import io.eigr.spawn.internal.Entity;
1112
import io.eigr.spawn.internal.client.OkHttpSpawnClient;
1213
import io.eigr.spawn.internal.client.SpawnClient;
@@ -62,11 +63,6 @@ public String getSystem() {
6263
return system;
6364
}
6465

65-
public void start() throws Exception {
66-
startServer();
67-
registerActorSystem();
68-
}
69-
7066
public ActorRef createActorRef(String system, String name) throws Exception {
7167
return ActorRef.of(this.client, system, name);
7268
}
@@ -75,9 +71,14 @@ public ActorRef createActorRef(String system, String name, String parent) throws
7571
return ActorRef.of(this.client, system, name, parent);
7672
}
7773

74+
public void start() throws Exception {
75+
startServer();
76+
registerActorSystem();
77+
}
78+
7879
private void startServer() throws IOException {
7980
HttpServer httpServer = HttpServer.create(new InetSocketAddress("127.0.0.1", this.port), 0);
80-
httpServer.createContext("/api/v1/actors/actions", new ActorServiceHandler(this.system, this.entities));
81+
httpServer.createContext("/api/v1/actors/actions", new ActorServiceHandler(this, this.entities));
8182
//httpServer.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
8283
httpServer.setExecutor(Executors.newCachedThreadPool());
8384
httpServer.start();
@@ -154,15 +155,15 @@ private Map<String, ActorOuterClass.Actor> getActors(List<Entity> entities) {
154155
)
155156
.setMetadata(metadata)
156157
.setSettings(settings)
157-
.addAllActions(getCommands(actorEntity))
158-
.addAllTimerActions(getTimerCommands(actorEntity))
158+
.addAllActions(getActions(actorEntity))
159+
.addAllTimerActions(getTimerActions(actorEntity))
159160
.setState(ActorOuterClass.ActorState.newBuilder().build())
160161
.build();
161162

162163
}).collect(Collectors.toMap(actor -> actor.getId().getName(), Function.identity()));
163164
}
164165

165-
private List<ActorOuterClass.Action> getCommands(Entity actorEntity) {
166+
private List<ActorOuterClass.Action> getActions(Entity actorEntity) {
166167
return actorEntity.getActions()
167168
.values()
168169
.stream()
@@ -175,7 +176,7 @@ private List<ActorOuterClass.Action> getCommands(Entity actorEntity) {
175176
.collect(Collectors.toList());
176177
}
177178

178-
private List<ActorOuterClass.FixedTimerAction> getTimerCommands(Entity actorEntity) {
179+
private List<ActorOuterClass.FixedTimerAction> getTimerActions(Entity actorEntity) {
179180
List<ActorOuterClass.FixedTimerAction> timerActions = actorEntity.getTimerActions()
180181
.values()
181182
.stream()
@@ -195,6 +196,17 @@ private List<ActorOuterClass.FixedTimerAction> getTimerCommands(Entity actorEnti
195196
return timerActions;
196197
}
197198

199+
@Override
200+
public String toString() {
201+
return new StringJoiner(", ", Spawn.class.getSimpleName() + "[", "]")
202+
.add("system='" + system + "'")
203+
.add("port=" + port)
204+
.add("proxyHost='" + proxyHost + "'")
205+
.add("proxyPort=" + proxyPort)
206+
.add("host='" + host + "'")
207+
.toString();
208+
}
209+
198210
public static final class SpawnSystem {
199211

200212
private SpawnClient client;
@@ -224,30 +236,60 @@ public SpawnSystem withProxyPort(int port) {
224236
return this;
225237
}
226238

227-
public SpawnSystem withActor(Class<?> actorKlass) {
239+
public SpawnSystem addActor(Class<?> actorKlass) {
228240
Optional<Entity> maybeEntity = getEntity(actorKlass);
229241
if (maybeEntity.isPresent()) {
230242
this.entities.add(maybeEntity.get());
231243
}
232244
return this;
233245
}
234246

247+
public SpawnSystem addActorWithArgs(Class<?> actorKlass, Object arg, ActorFactory factory) {
248+
Optional<Entity> maybeEntity = getEntity(actorKlass, arg, factory);
249+
if (maybeEntity.isPresent()) {
250+
this.entities.add(maybeEntity.get());
251+
}
252+
return this;
253+
}
254+
235255
public Spawn build() {
236256
this.client = new OkHttpSpawnClient(this.system, this.proxyHost, this.proxyPort);
237257
return new Spawn(this);
238258
}
239259

240260
private Optional<Entity> getEntity(Class<?> actorKlass) {
241261
if (Objects.nonNull(actorKlass.getAnnotation(NamedActor.class))) {
242-
return Optional.of(Entity.fromAnnotationToEntity(actorKlass, actorKlass.getAnnotation(NamedActor.class)));
262+
return Optional.of(Entity.fromAnnotationToEntity(
263+
actorKlass, actorKlass.getAnnotation(NamedActor.class), null, null));
243264
}
244265

245266
if (Objects.nonNull(actorKlass.getAnnotation(UnNamedActor.class))) {
246-
return Optional.of(Entity.fromAnnotationToEntity(actorKlass, actorKlass.getAnnotation(UnNamedActor.class)));
267+
return Optional.of(Entity.fromAnnotationToEntity(
268+
actorKlass, actorKlass.getAnnotation(UnNamedActor.class), null, null));
247269
}
248270

249271
if (Objects.nonNull(actorKlass.getAnnotation(PooledActor.class))) {
250-
return Optional.of(Entity.fromAnnotationToEntity(actorKlass, actorKlass.getAnnotation(PooledActor.class)));
272+
return Optional.of(Entity.fromAnnotationToEntity(
273+
actorKlass, actorKlass.getAnnotation(PooledActor.class), null, null));
274+
}
275+
276+
return Optional.empty();
277+
}
278+
279+
private Optional<Entity> getEntity(Class<?> actorType, Object arg, ActorFactory factory) {
280+
if (Objects.nonNull(actorType.getAnnotation(NamedActor.class))) {
281+
NamedActor annotation = actorType.getAnnotation(NamedActor.class);
282+
return Optional.of(Entity.fromAnnotationToEntity(actorType, annotation, arg, factory));
283+
}
284+
285+
if (Objects.nonNull(actorType.getAnnotation(UnNamedActor.class))) {
286+
UnNamedActor annotation = actorType.getAnnotation(UnNamedActor.class);
287+
return Optional.of(Entity.fromAnnotationToEntity(actorType, annotation, arg, factory));
288+
}
289+
290+
if (Objects.nonNull(actorType.getAnnotation(PooledActor.class))) {
291+
PooledActor annotation = actorType.getAnnotation(PooledActor.class);
292+
return Optional.of(Entity.fromAnnotationToEntity(actorType, annotation, arg, factory));
251293
}
252294

253295
return Optional.empty();

src/main/java/io/eigr/spawn/api/Value.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package io.eigr.spawn.api;
22

33
import com.google.protobuf.GeneratedMessageV3;
4-
import io.eigr.spawn.api.workflows.Broadcast;
5-
import io.eigr.spawn.api.workflows.Forward;
6-
import io.eigr.spawn.api.workflows.Pipe;
7-
import io.eigr.spawn.api.workflows.SideEffect;
4+
import io.eigr.spawn.api.actors.workflows.Broadcast;
5+
import io.eigr.spawn.api.actors.workflows.Forward;
6+
import io.eigr.spawn.api.actors.workflows.Pipe;
7+
import io.eigr.spawn.api.actors.workflows.SideEffect;
88

99
import java.util.List;
1010
import java.util.Objects;

0 commit comments

Comments
 (0)