@@ -90,7 +90,7 @@ The second thing we have to do is add the spawn dependency to the project.
9090<dependency >
9191 <groupId >com.github.eigr</groupId >
9292 <artifactId >spawn-java-std-sdk</artifactId >
93- <version >v0.3.3 </version >
93+ <version >v0.3.4 </version >
9494</dependency >
9595```
9696We're also going to configure a few things for our application build to work, including compiling the protobuf files.
@@ -124,7 +124,7 @@ See below a full example of the pom.xml file:
124124 <dependency >
125125 <groupId >com.github.eigr</groupId >
126126 <artifactId >spawn-java-std-sdk</artifactId >
127- <version >v0.3.3 </version >
127+ <version >v0.3.4 </version >
128128 </dependency >
129129 <dependency >
130130 <groupId >ch.qos.logback</groupId >
@@ -576,8 +576,37 @@ Actors can also emit side effects to other Actors as part of their response.
576576See an example:
577577
578578``` Java
579+ package io.eigr.spawn.java.demo ;
580+
581+ import io.eigr.spawn.api.Value ;
582+ import io.eigr.spawn.api.actors.ActorContext ;
583+ import io.eigr.spawn.api.actors.ActorRef ;
584+ import io.eigr.spawn.api.actors.annotations.Action ;
585+ import io.eigr.spawn.api.actors.annotations.NamedActor ;
586+ import io.eigr.spawn.api.actors.workflows.SideEffect ;
587+ import io.eigr.spawn.java.demo.domain.Domain ;
588+
589+ @NamedActor (name = " side_effect_actor" , stateful = true , stateType = Domain . State . class)
590+ public class SideEffectActorExample {
591+ @Action
592+ public Value setLanguage (Domain .Request msg , ActorContext<Domain . State > ctx ) throws Exception {
593+ // Create a ActorReference to send side effect message
594+ ActorRef sideEffectReceiverActor = ctx. getSpawnSystem()
595+ .createActorRef(" spawn-system" , " mike" , " abs_actor" );
579596
597+ return Value . at()
598+ .response(Domain . Reply . newBuilder()
599+ .setResponse(" Hello From Java" )
600+ .build())
601+ .state(updateState(" java" ))
602+ .flow(SideEffect . to(sideEffectReceiverActor, " setLanguage" , msg))
603+ // .flow(SideEffect.to(emailSenderReceiverActor, "sendEmail", emailMessage))
604+ // .flow(SideEffect.to(otherReceiverActor, "otherAction", otherMessage))
605+ .noReply();
606+ }
580607
608+ // ....
609+ }
581610```
582611
583612Side effects such as broadcast are not part of the response flow to the caller. They are request-asynchronous events that
@@ -593,7 +622,36 @@ an action in another Actor.
593622See an example:
594623
595624``` Java
625+ package io.eigr.spawn.java.demo ;
596626
627+ import io.eigr.spawn.api.Value ;
628+ import io.eigr.spawn.api.actors.ActorContext ;
629+ import io.eigr.spawn.api.actors.ActorRef ;
630+ import io.eigr.spawn.api.actors.annotations.Action ;
631+ import io.eigr.spawn.api.actors.annotations.NamedActor ;
632+ import io.eigr.spawn.api.actors.workflows.Forward ;
633+ import io.eigr.spawn.java.demo.domain.Domain ;
634+ import org.slf4j.Logger ;
635+ import org.slf4j.LoggerFactory ;
636+
637+ @NamedActor (name = " routing_actor" , stateful = true , stateType = Domain . State . class)
638+ public class ForwardExample {
639+ private static final Logger log = LoggerFactory . getLogger(ForwardExample . class);
640+
641+ @Action
642+ public Value setLanguage (Domain .Request msg , ActorContext<Domain . State > ctx ) throws Exception {
643+ log. info(" Received invocation. Message: {}. Context: {}" , msg, ctx);
644+ if (ctx. getState(). isPresent()) {
645+ log. info(" State is present and value is {}" , ctx. getState(). get());
646+ }
647+ ActorRef forwardedActor = ctx. getSpawnSystem()
648+ .createActorRef(" spawn-system" , " mike" , " abs_actor" );
649+
650+ return Value . at()
651+ .flow(Forward . to(forwardedActor," setLanguage" ))
652+ .noReply();
653+ }
654+ }
597655```
598656
599657### Pipe
@@ -606,7 +664,39 @@ In the end, just like in a Forward, it is the response of the last Actor in the
606664Example:
607665
608666``` Java
667+ package io.eigr.spawn.java.demo ;
668+
669+ import io.eigr.spawn.api.Value ;
670+ import io.eigr.spawn.api.actors.ActorContext ;
671+ import io.eigr.spawn.api.actors.ActorRef ;
672+ import io.eigr.spawn.api.actors.annotations.Action ;
673+ import io.eigr.spawn.api.actors.annotations.NamedActor ;
674+ import io.eigr.spawn.api.actors.workflows.Pipe ;
675+ import io.eigr.spawn.java.demo.domain.Domain ;
676+
677+ @NamedActor (name = " pipe_actor" , stateful = true , stateType = Domain . State . class)
678+ public class PipeActorExample {
679+
680+ @Action
681+ public Value setLanguage (Domain .Request msg , ActorContext<Domain . State > ctx ) throws Exception {
682+ ActorRef pipeReceiverActor = ctx. getSpawnSystem()
683+ .createActorRef(" spawn-system" , " joe" );
684+
685+ return Value . at()
686+ .response(Domain . Reply . newBuilder()
687+ .setResponse(" Hello From Java" )
688+ .build())
689+ .flow(Pipe . to(pipeReceiverActor, " someAction" ))
690+ .state(updateState(" java" ))
691+ .noReply();
692+ }
609693
694+ private Domain .State updateState (String language ) {
695+ return Domain . State . newBuilder()
696+ .addLanguages(language)
697+ .build();
698+ }
699+ }
610700```
611701
612702Forwards and pipes do not have an upper thread limit other than the request timeout.
@@ -622,8 +712,8 @@ during the moment of the Actor's deactivation.
622712That is, data is saved at regular intervals asynchronously while the Actor is active and once synchronously
623713when the Actor suffers a deactivation, when it is turned off.
624714
625- These snapshots happen from time to time. And this time is configurable through the *** snapshot_timeout *** property of
626- the *** ActorSettings *** class.
715+ These snapshots happen from time to time. And this time is configurable through the *** snapshotTimeout *** property of
716+ the *** NamedActor *** or *** UnNamedActor *** class.
627717However, you can tell the Spawn runtime that you want it to persist the data immediately synchronously after executing an Action.
628718And this can be done in the following way:
629719
@@ -736,6 +826,32 @@ name given to the actor that defines the ActorRef template.
736826To better exemplify, let's first show the Actor's definition code and later how we would call this actor with a concrete
737827name at runtime:
738828
829+ ``` java
830+ package io.eigr.spawn.java.demo ;
831+ // omitted imports for brevity...
832+
833+ @UnNamedActor (name = " abs_actor" , stateful = true , stateType = Domain . State . class)
834+ public class AbstractActor {
835+ @Action (inputType = Domain . Request . class)
836+ public Value setLanguage (Domain .Request msg , ActorContext<Domain . State > context ) {
837+ return Value . at()
838+ .response(Domain . Reply . newBuilder()
839+ .setResponse(" Hello From Java" )
840+ .build())
841+ .state(updateState(" java" ))
842+ .reply();
843+ }
844+
845+ private Domain .State updateState (String language ) {
846+ return Domain . State . newBuilder()
847+ .addLanguages(language)
848+ .build();
849+ }
850+ }
851+ ```
852+
853+ So you could define and call this actor at runtime like this:
854+
739855``` Java
740856ActorRef mike = spawnSystem. createActorRef(" spawn-system" , " mike" , " abs_actor" );
741857
0 commit comments