Skip to content

Commit eacdf72

Browse files
committed
Add support for timeouts
1 parent 9cfbc8f commit eacdf72

File tree

5 files changed

+70
-10
lines changed

5 files changed

+70
-10
lines changed

README.md

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ JVM User Language Support for [Spawn](https://github.com/eigr/spawn).
1717
4. [Using Actors](#using-actors)
1818
- [Call Named Actors](#call-named-actors)
1919
- [Call Unnamed Actors](#call-unnamed-actors)
20-
- [Async and other options](#async-calls-and-other-options)
20+
- [Async](#async)
21+
- [Timeouts](#timeouts)
2122
5. [Deploy](#deploy)
2223
- [Defining an ActorSystem](#defining-an-actorsytem)
2324
- [Defining an ActorHost](#defining-an-actorhost)
@@ -92,7 +93,7 @@ The second thing we have to do is add the spawn dependency to the project.
9293
<dependency>
9394
<groupId>com.github.eigr</groupId>
9495
<artifactId>spawn-java-std-sdk</artifactId>
95-
<version>v0.6.2</version>
96+
<version>v0.6.5</version>
9697
</dependency>
9798
```
9899
We're also going to configure a few things for our application build to work, including compiling the protobuf files.
@@ -126,7 +127,7 @@ See below a full example of the pom.xml file:
126127
<dependency>
127128
<groupId>com.github.eigr</groupId>
128129
<artifactId>spawn-java-std-sdk</artifactId>
129-
<version>v0.6.2</version>
130+
<version>v0.6.5</version>
130131
</dependency>
131132
<dependency>
132133
<groupId>ch.qos.logback</groupId>
@@ -837,8 +838,8 @@ Domain.Request msg = Domain.Request.newBuilder()
837838
.setLanguage("erlang")
838839
.build();
839840

840-
Optional<Object> maybeResponse = joeActor.invoke("setLanguage", msg, Domain.Reply.class);
841-
Domain.Reply reply = (Domain.Reply)maybeResponse.get();
841+
Optional<Domain.Reply> maybeResponse = joeActor.invoke("setLanguage", msg, Domain.Reply.class);
842+
Domain.Reply reply = maybeResponse.get();
842843
```
843844

844845
More detailed in complete main class:
@@ -874,7 +875,7 @@ public class App {
874875
.build();
875876

876877
Optional<Object> maybeResponse = joeActor.invoke("setLanguage", msg, Domain.Reply.class);
877-
Domain.Reply reply = (Domain.Reply)maybeResponse.get();
878+
Domain.Reply reply = maybeResponse.get();
878879
}
879880
}
880881
```
@@ -920,8 +921,8 @@ Domain.Request msg = Domain.Request.newBuilder()
920921
.setLanguage("erlang")
921922
.build();
922923

923-
Optional<Object> maybeResponse = mike.invoke("setLanguage", msg, Domain.Reply.class);
924-
Domain.Reply reply = (Domain.Reply)maybeResponse.get();
924+
Optional<Domain.Reply> maybeResponse = mike.invoke("setLanguage", msg, Domain.Reply.class);
925+
Domain.Reply reply = maybeResponse.get();
925926
```
926927

927928
The important part of the code above is the following snippet:
@@ -934,7 +935,7 @@ These tells Spawn that this actor will actually be named at runtime. The name pa
934935
in this case is just a reference to "abs_actor" Actor that will be used later
935936
so that we can actually create an instance of the real Actor.
936937

937-
### Async calls and other options
938+
### Async
938939

939940
Basically Spawn can perform actor functions in two ways. Synchronously, where the callee waits for a response,
940941
or asynchronously, where the callee doesn't care about the return value of the call.
@@ -947,6 +948,45 @@ Therefore, to call an actor's function asynchronously, just use the invokeAsync
947948
mike.invokeAsync("setLanguage", msg);
948949
```
949950

951+
### Timeouts
952+
953+
It is possible to change the request waiting timeout using the invocation options as below:
954+
955+
```Java
956+
package io.eigr.spawn.java.demo;
957+
958+
import io.eigr.spawn.api.ActorRef;
959+
import io.eigr.spawn.api.InvocationOpts;
960+
import io.eigr.spawn.api.Spawn;
961+
import io.eigr.spawn.api.TransportOpts;
962+
import io.eigr.spawn.java.demo.domain.Domain;
963+
964+
import java.util.Optional;
965+
966+
public class App {
967+
public static void main(String[] args) throws Exception {
968+
Spawn spawnSystem = new Spawn.SpawnSystem()
969+
.create("spawn-system")
970+
.withActor(Joe.class)
971+
.build();
972+
973+
spawnSystem.start();
974+
975+
ActorRef joeActor = spawnSystem.createActorRef("spawn-system", "joe");
976+
977+
Domain.Request msg = Domain.Request.newBuilder()
978+
.setLanguage("erlang")
979+
.build();
980+
981+
InvocationOpts opts = InvocationOpts.builder()
982+
.timeoutSeconds(Duration.ofSeconds(30))
983+
.build();
984+
985+
Optional<Domain.Reply> maybeResponse = joeActor.invoke("setLanguage", msg, Domain.Reply.class, opts);
986+
}
987+
}
988+
```
989+
950990
## Deploy
951991

952992
See [Getting Started](https://github.com/eigr/spawn#getting-started) section from the main Spawn repository for more

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<groupId>io.eigr.spawn</groupId>
55
<artifactId>spawn-java-std-sdk</artifactId>
66
<packaging>jar</packaging>
7-
<version>0.6.2</version>
7+
<version>0.6.5</version>
88
<name>spawn-java-std-sdk</name>
99
<url>http://maven.apache.org</url>
1010

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import io.eigr.spawn.internal.transport.client.SpawnClient;
1313

1414
import java.time.Duration;
15+
import java.util.HashMap;
16+
import java.util.Map;
1517
import java.util.Objects;
1618
import java.util.Optional;
1719

@@ -216,6 +218,7 @@ public <T extends GeneratedMessageV3> void invokeAsync(String action, Invocation
216218
.async(true)
217219
.delay(opts.getDelay())
218220
.scheduledTo(opts.getScheduledTo())
221+
.timeoutSeconds(opts.getTimeoutSeconds())
219222
.build();
220223

221224
invokeActor(action, Empty.getDefaultInstance(), null, Optional.ofNullable(mergedOpts));
@@ -251,6 +254,7 @@ public <T extends GeneratedMessageV3, S extends GeneratedMessageV3> void invokeA
251254
.async(true)
252255
.delay(opts.getDelay())
253256
.scheduledTo(opts.getScheduledTo())
257+
.timeoutSeconds(opts.getTimeoutSeconds())
254258
.build();
255259

256260
invokeActor(action, value, null, Optional.of(mergedOpts));
@@ -286,6 +290,7 @@ private <T extends GeneratedMessageV3, S extends GeneratedMessageV3> Optional<T>
286290

287291
Protocol.InvocationRequest.Builder invocationRequestBuilder = Protocol.InvocationRequest.newBuilder();
288292

293+
Map<String, String> metadata = new HashMap<>();
289294
if (options.isPresent()) {
290295
InvocationOpts opts = options.get();
291296
invocationRequestBuilder.setAsync(opts.isAsync());
@@ -295,6 +300,8 @@ private <T extends GeneratedMessageV3, S extends GeneratedMessageV3> Optional<T>
295300
} else if (opts.getScheduledTo().isPresent()) {
296301
invocationRequestBuilder.setScheduledTo(opts.getScheduleTimeInLong());
297302
}
303+
304+
metadata.put("request-timeout", String.valueOf(opts.getTimeout()));
298305
}
299306

300307
final ActorOuterClass.Actor actorRef = ActorOuterClass.Actor.newBuilder()
@@ -303,11 +310,14 @@ private <T extends GeneratedMessageV3, S extends GeneratedMessageV3> Optional<T>
303310

304311
Any commandArg = Any.pack(argument);
305312

313+
314+
306315
invocationRequestBuilder
307316
.setSystem(ActorOuterClass.ActorSystem.newBuilder().setName(this.actorId.getSystem()).build())
308317
.setActor(actorRef)
309318
.setActionName(cmd)
310319
.setValue(commandArg)
320+
.putAllMetadata(metadata)
311321
.build();
312322

313323
Protocol.InvocationResponse resp = this.client.invoke(invocationRequestBuilder.build());

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.Getter;
66
import lombok.NoArgsConstructor;
77

8+
import java.time.Duration;
89
import java.time.LocalDateTime;
910
import java.time.temporal.ChronoUnit;
1011
import java.util.Optional;
@@ -18,6 +19,9 @@ public class InvocationOpts {
1819
@Builder.Default
1920
private boolean async = false;
2021

22+
@Builder.Default
23+
private Duration timeoutSeconds = Duration.ofSeconds(10);
24+
2125
@Builder.Default
2226
private Optional<Long> delay = Optional.empty();
2327

@@ -32,4 +36,8 @@ public long getScheduleTimeInLong() {
3236

3337
return 0;
3438
}
39+
40+
public long getTimeout() {
41+
return this.timeoutSeconds.toMillis();
42+
}
3543
}

src/test/java/io/eigr/spawn/SpawnTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.eigr.spawn;
22

3+
import io.eigr.spawn.api.InvocationOpts;
34
import io.eigr.spawn.api.Spawn;
45
import io.eigr.spawn.api.ActorRef;
56
import io.eigr.spawn.api.TransportOpts;
@@ -8,6 +9,7 @@
89
import org.junit.Before;
910
import org.junit.Test;
1011

12+
import java.time.Duration;
1113
import java.util.Optional;
1214

1315
import static org.junit.Assert.assertEquals;

0 commit comments

Comments
 (0)