11package io .eigr .spawn .api .actors ;
22
3+ import com .google .protobuf .Any ;
4+ import com .google .protobuf .Empty ;
5+ import com .google .protobuf .GeneratedMessageV3 ;
6+ import io .eigr .functions .protocol .Protocol ;
7+ import io .eigr .functions .protocol .actors .ActorOuterClass ;
8+ import io .eigr .spawn .api .InvocationOpts ;
9+ import io .eigr .spawn .api .exceptions .ActorInvokeException ;
10+ import io .eigr .spawn .api .exceptions .ActorNotFoundException ;
311import io .eigr .spawn .internal .client .SpawnClient ;
412
513import java .util .Optional ;
614
715public final class ActorRef {
816
17+ private final ActorOuterClass .ActorId actorId ;
18+
919 private final String name ;
1020
1121 private final String system ;
1222
1323 private final Optional <String > parent ;
24+
1425 private final SpawnClient client ;
1526
16- private ActorRef (SpawnClient client , String system , String name ) {
27+ private ActorRef (SpawnClient client , String system , String name ) throws Exception {
1728 this .client = client ;
1829 this .system = system ;
1930 this .name = name ;
2031 this .parent = Optional .empty ();
32+ this .actorId = buildActorId ();
33+ if (this .parent .isPresent ()){
34+ makeActor ();
35+ }
2136 }
22- private ActorRef (SpawnClient client , String system , String name , String parent ) {
37+
38+ private ActorRef (SpawnClient client , String system , String name , String parent ) throws Exception {
2339 this .client = client ;
2440 this .system = system ;
2541 this .name = name ;
2642 this .parent = Optional .of (parent );
43+ this .actorId = buildActorId ();
44+ if (this .parent .isPresent ()){
45+ makeActor ();
46+ }
2747 }
2848
29- public static ActorRef of (SpawnClient client , String system , String name ) {
49+
50+ public static ActorRef of (SpawnClient client , String system , String name ) throws Exception {
3051 return new ActorRef (client , system , name );
3152 }
3253
33- public static ActorRef of (SpawnClient client , String system , String name , String parent ) {
54+ public static ActorRef of (SpawnClient client , String system , String name , String parent ) throws Exception {
3455 return new ActorRef (client , system , name , parent );
3556 }
3657
58+ public <T extends GeneratedMessageV3 > Object invoke (String cmd , Class <T > outputType , Optional <InvocationOpts > opts ) throws Exception {
59+ return invokeActor (cmd , Empty .getDefaultInstance (), outputType , opts );
60+ }
61+
62+ public <T extends GeneratedMessageV3 , S extends GeneratedMessageV3 > Object invoke (String cmd , S value , Class <T > outputType , Optional <InvocationOpts > opts ) throws Exception {
63+ return invokeActor (cmd , value , outputType , opts );
64+ }
65+
3766 public String getActorSystem () {
3867 return this .system ;
3968 }
@@ -53,4 +82,71 @@ public String getActorParentName() {
5382 public boolean isUnnamedActor () {
5483 return Optional .empty ().isPresent ();
5584 }
85+
86+ private ActorOuterClass .ActorId buildActorId () {
87+ ActorOuterClass .ActorId .Builder actorIdBuilder = ActorOuterClass .ActorId .newBuilder ()
88+ .setSystem (this .system )
89+ .setName (this .name );
90+
91+ if (this .parent .isPresent ()) {
92+ actorIdBuilder .setParent (this .parent .get ());
93+ }
94+
95+ return actorIdBuilder .build ();
96+ }
97+
98+ private void makeActor () throws Exception {
99+ Protocol .SpawnRequest req = Protocol .SpawnRequest .newBuilder ()
100+ .addActors (this .actorId )
101+ .build ();
102+ this .client .spawn (req );
103+ }
104+
105+ private <T extends GeneratedMessageV3 , S extends GeneratedMessageV3 > Object invokeActor (String cmd , S argument , Class <T > outputType , Optional <InvocationOpts > options ) throws Exception {
106+ Protocol .InvocationRequest .Builder invocationRequestBuilder = Protocol .InvocationRequest .newBuilder ();
107+
108+ if (options .isPresent ()) {
109+ InvocationOpts opts = options .get ();
110+ invocationRequestBuilder .setAsync (opts .isAsync ());
111+
112+ if (opts .getDelay ().isPresent () && !opts .getScheduledTo ().isPresent ()) {
113+ invocationRequestBuilder .setScheduledTo (opts .getDelay ().get ());
114+ } else if (opts .getScheduledTo ().isPresent ()) {
115+ invocationRequestBuilder .setScheduledTo (opts .getScheduleTimeInLong ());
116+ }
117+ }
118+
119+ final ActorOuterClass .Actor actorRef = ActorOuterClass .Actor .newBuilder ()
120+ .setId (this .actorId )
121+ .build ();
122+
123+ Any commandArg = Any .pack (argument );
124+
125+ invocationRequestBuilder
126+ .setSystem (ActorOuterClass .ActorSystem .newBuilder ().setName (this .system ).build ())
127+ .setActor (actorRef )
128+ .setActionName (cmd )
129+ .setValue (commandArg )
130+ .build ();
131+
132+ Protocol .InvocationResponse resp = this .client .invoke (invocationRequestBuilder .build ());
133+ final Protocol .RequestStatus status = resp .getStatus ();
134+ switch (status .getStatus ()) {
135+ case UNKNOWN :
136+ case ERROR :
137+ case UNRECOGNIZED :
138+ throw new ActorInvokeException (
139+ String .format ("Unknown error when trying to invoke Actor %s" , this .name ));
140+ case ACTOR_NOT_FOUND :
141+ throw new ActorNotFoundException ();
142+ case OK :
143+ if (resp .hasValue ()) {
144+ return outputType .cast (resp .getValue ()
145+ .unpack (outputType ));
146+ }
147+ return null ;
148+ }
149+
150+ throw new ActorNotFoundException ();
151+ }
56152}
0 commit comments