Skip to content

Commit 0908adf

Browse files
committed
Synchronize the calls subscription observer (underlying ServerCallImpl isn't thread-safe).
Allow to set the `Executor` for `GrpcContainer`. Bump the library version to `1.7.5`.
1 parent 69dd272 commit 0908adf

File tree

6 files changed

+107
-31
lines changed

6 files changed

+107
-31
lines changed

license-report.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22

3-
# Dependencies of `io.spine:spine-client:1.7.1`
3+
# Dependencies of `io.spine:spine-client:1.7.5`
44

55
## Runtime
66
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -399,12 +399,12 @@
399399
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
400400

401401

402-
This report was generated on **Fri Jan 08 14:16:21 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
402+
This report was generated on **Mon Jul 26 22:39:51 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
403403

404404

405405

406406

407-
# Dependencies of `io.spine:spine-core:1.7.1`
407+
# Dependencies of `io.spine:spine-core:1.7.5`
408408

409409
## Runtime
410410
1. **Group:** com.google.code.findbugs **Name:** jsr305 **Version:** 3.0.2
@@ -763,12 +763,12 @@ This report was generated on **Fri Jan 08 14:16:21 EET 2021** using [Gradle-Lice
763763
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
764764

765765

766-
This report was generated on **Fri Jan 08 14:16:22 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
766+
This report was generated on **Mon Jul 26 22:39:51 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
767767

768768

769769

770770

771-
# Dependencies of `io.spine.tools:spine-model-assembler:1.7.1`
771+
# Dependencies of `io.spine.tools:spine-model-assembler:1.7.5`
772772

773773
## Runtime
774774
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -1162,12 +1162,12 @@ This report was generated on **Fri Jan 08 14:16:22 EET 2021** using [Gradle-Lice
11621162
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
11631163

11641164

1165-
This report was generated on **Fri Jan 08 14:16:22 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
1165+
This report was generated on **Mon Jul 26 22:39:51 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
11661166

11671167

11681168

11691169

1170-
# Dependencies of `io.spine.tools:spine-model-verifier:1.7.1`
1170+
# Dependencies of `io.spine.tools:spine-model-verifier:1.7.5`
11711171

11721172
## Runtime
11731173
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -1627,12 +1627,12 @@ This report was generated on **Fri Jan 08 14:16:22 EET 2021** using [Gradle-Lice
16271627
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
16281628

16291629

1630-
This report was generated on **Fri Jan 08 14:16:23 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
1630+
This report was generated on **Mon Jul 26 22:39:52 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
16311631

16321632

16331633

16341634

1635-
# Dependencies of `io.spine:spine-server:1.7.1`
1635+
# Dependencies of `io.spine:spine-server:1.7.5`
16361636

16371637
## Runtime
16381638
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2039,12 +2039,12 @@ This report was generated on **Fri Jan 08 14:16:23 EET 2021** using [Gradle-Lice
20392039
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
20402040

20412041

2042-
This report was generated on **Fri Jan 08 14:16:23 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
2042+
This report was generated on **Mon Jul 26 22:39:52 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
20432043

20442044

20452045

20462046

2047-
# Dependencies of `io.spine:spine-testutil-client:1.7.1`
2047+
# Dependencies of `io.spine:spine-testutil-client:1.7.5`
20482048

20492049
## Runtime
20502050
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2493,12 +2493,12 @@ This report was generated on **Fri Jan 08 14:16:23 EET 2021** using [Gradle-Lice
24932493
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
24942494

24952495

2496-
This report was generated on **Fri Jan 08 14:16:25 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
2496+
This report was generated on **Mon Jul 26 22:39:54 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
24972497

24982498

24992499

25002500

2501-
# Dependencies of `io.spine:spine-testutil-core:1.7.1`
2501+
# Dependencies of `io.spine:spine-testutil-core:1.7.5`
25022502

25032503
## Runtime
25042504
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -2947,12 +2947,12 @@ This report was generated on **Fri Jan 08 14:16:25 EET 2021** using [Gradle-Lice
29472947
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
29482948

29492949

2950-
This report was generated on **Fri Jan 08 14:16:26 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
2950+
This report was generated on **Mon Jul 26 22:39:55 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
29512951

29522952

29532953

29542954

2955-
# Dependencies of `io.spine:spine-testutil-server:1.7.1`
2955+
# Dependencies of `io.spine:spine-testutil-server:1.7.5`
29562956

29572957
## Runtime
29582958
1. **Group:** com.google.android **Name:** annotations **Version:** 4.1.1.4
@@ -3445,4 +3445,4 @@ This report was generated on **Fri Jan 08 14:16:26 EET 2021** using [Gradle-Lice
34453445
The dependencies distributed under several licenses, are used according their commercial-use-friendly license.
34463446

34473447

3448-
This report was generated on **Fri Jan 08 14:16:30 EET 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).
3448+
This report was generated on **Mon Jul 26 22:39:57 EEST 2021** using [Gradle-License-Report plugin](https://github.com/jk1/Gradle-License-Report) by Evgeny Naumenko, licensed under [Apache 2.0 License](https://github.com/jk1/Gradle-License-Report/blob/master/LICENSE).

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.
1212

1313
<groupId>io.spine</groupId>
1414
<artifactId>spine-core-java</artifactId>
15-
<version>1.7.1</version>
15+
<version>1.7.5</version>
1616

1717
<inceptionYear>2015</inceptionYear>
1818

server/src/main/java/io/spine/server/GrpcContainer.java

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@
4242
import java.io.IOException;
4343
import java.util.Optional;
4444
import java.util.Set;
45+
import java.util.concurrent.Executor;
4546

4647
import static com.google.common.base.Preconditions.checkNotNull;
4748
import static com.google.common.base.Preconditions.checkState;
4849
import static java.lang.String.format;
50+
import static java.util.Objects.requireNonNull;
4951

5052
/**
5153
* Wrapping container for gRPC server.
@@ -54,6 +56,7 @@
5456
*
5557
* <p>Uses {@link ServerServiceDefinition}s of each service.
5658
*/
59+
@SuppressWarnings("ClassWithTooManyMethods") /* Extensive configuration. */
5760
public final class GrpcContainer {
5861

5962
private static final String SERVER_NOT_STARTED_MSG =
@@ -128,15 +131,41 @@ public Optional<String> serverName() {
128131
/**
129132
* Starts the service.
130133
*
134+
* <p>A gRPC-default executor is used for the server routines. I.e., in-process gRPC server
135+
* is going to run on top of a {@linkplain ServerBuilder#directExecutor() direct executor},
136+
* and a server exposed at a port will run on top of a shared cached thread pool.
137+
*
138+
* <p>See the {@link ServerBuilder} Javadocs corresponding to the current gRPC version
139+
* for more details.
140+
*
131141
* @throws IOException
132142
* if unable to bind
133143
*/
134144
public void start() throws IOException {
135-
checkState(grpcServer == null, "gRPC server is started already.");
136-
grpcServer = createGrpcServer();
145+
checkNotStarted();
146+
grpcServer = createGrpcServer(/* ...with a gRPC-default executor. */ null);
147+
grpcServer.start();
148+
}
149+
150+
/**
151+
* Starts the service on top of the given {@code Executor}.
152+
*
153+
* @param executor
154+
* an executor to use for gRPC server
155+
* @throws IOException
156+
* if unable to bind
157+
*/
158+
public void start(Executor executor) throws IOException {
159+
checkNotStarted();
160+
checkNotNull(executor, "Executor must not be `null`.");
161+
grpcServer = createGrpcServer(executor);
137162
grpcServer.start();
138163
}
139164

165+
private void checkNotStarted() {
166+
checkState(grpcServer == null, "gRPC server is started already.");
167+
}
168+
140169
/**
141170
* Returns {@code true} if the server is shut down or was not started at all,
142171
* {@code false} otherwise.
@@ -238,30 +267,64 @@ public void addShutdownHook() {
238267
.addShutdownHook(new Thread(shutdownCallback()));
239268
}
240269

241-
private Server createGrpcServer() {
270+
/**
271+
* Creates a gRPC server which uses a specified executor.
272+
*
273+
* <p>If {@code null} is passed, a default behavior of the gRPC {@link ServerBuilder}
274+
* is applied.
275+
*
276+
* @param executor
277+
* executor to use for the gRPC server
278+
*/
279+
private Server createGrpcServer(@Nullable Executor executor) {
242280
if (injectedServer != null) {
243281
return injectedServer;
244282
}
245-
ServerBuilder builder = createServerBuilder();
283+
ServerBuilder<?> builder = createServerBuilder(executor);
246284
for (ServerServiceDefinition service : services) {
247285
builder.addService(service);
248286
}
249287
return builder.build();
250288
}
251289

252-
private ServerBuilder createServerBuilder() {
253-
ServerBuilder result =
290+
/**
291+
* Creates a builder of the gRPC server with the provided executor.
292+
*
293+
* <p>If {@code null} is passed, a default behavior of the gRPC {@link ServerBuilder}
294+
* is applied.
295+
*
296+
* @param executor
297+
* executor to configure for the created builder
298+
*/
299+
private ServerBuilder<?> createServerBuilder(@Nullable Executor executor) {
300+
ServerBuilder<?> result =
254301
serverName == null
255-
? ServerBuilder.forPort(checkNotNull(port))
256-
: InProcessServerBuilder.forName(serverName)
257-
.directExecutor();
302+
? builderAtPort(requireNonNull(port), executor)
303+
: inProcessBuilder(serverName, executor);
258304
return result;
259305
}
260306

307+
private static ServerBuilder<?> inProcessBuilder(String name, @Nullable Executor executor) {
308+
InProcessServerBuilder builder = InProcessServerBuilder.forName(name);
309+
builder = executor == null
310+
? builder.directExecutor()
311+
: builder.executor(executor);
312+
return builder;
313+
}
314+
315+
private static ServerBuilder<?> builderAtPort(Integer port, @Nullable Executor executor) {
316+
ServerBuilder<?> builder = ServerBuilder.forPort(port);
317+
builder = executor == null
318+
? builder
319+
: builder.executor(executor);
320+
return builder;
321+
}
322+
261323
/**
262324
* Injects a server to this container.
263325
*
264-
* <p>All calls to {@link #createGrpcServer()} will resolve to the given server instance.
326+
* <p>All calls to {@link #createGrpcServer(Executor)} will resolve to the given server
327+
* instance.
265328
*
266329
* <p>A test-only method.
267330
*/
@@ -356,6 +419,7 @@ public Builder removeService(ServerServiceDefinition service) {
356419

357420
/**
358421
* Obtains the services already added to the builder.
422+
*
359423
* @deprecated please use {@link #services()}.
360424
*/
361425
@Deprecated

server/src/main/java/io/spine/server/stand/SubscriptionCallback.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ public interface SubscriptionCallback extends Consumer<SubscriptionUpdate> {
4747
*/
4848
static SubscriptionCallback forwardingTo(StreamObserver<SubscriptionUpdate> observer) {
4949
return update -> {
50-
checkNotNull(update);
51-
observer.onNext(update);
50+
synchronized (observer) {
51+
checkNotNull(update);
52+
observer.onNext(update);
53+
}
5254
};
5355
}
5456
}

server/src/test/java/io/spine/server/GrpcContainerTest.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,15 @@
4242
import static com.google.common.truth.Truth.assertThat;
4343
import static com.google.common.truth.Truth8.assertThat;
4444
import static io.spine.testing.TestValues.randomString;
45+
import static java.util.concurrent.Executors.newSingleThreadExecutor;
4546
import static org.junit.jupiter.api.Assertions.assertEquals;
4647
import static org.junit.jupiter.api.Assertions.assertFalse;
4748
import static org.junit.jupiter.api.Assertions.assertNotNull;
4849
import static org.junit.jupiter.api.Assertions.assertThrows;
4950
import static org.junit.jupiter.api.Assertions.assertTrue;
5051
import static org.junit.jupiter.api.Assertions.fail;
5152

52-
@DisplayName("GrpcContainer should")
53+
@DisplayName("`GrpcContainer` should")
5354
class GrpcContainerTest {
5455

5556
private GrpcContainer grpcContainer;
@@ -99,6 +100,15 @@ void startServer() throws IOException {
99100
.isNotNull();
100101
}
101102

103+
@Test
104+
@DisplayName("start server with the given `Executor`")
105+
void startServerWithExecutor() throws IOException {
106+
grpcContainer.start(newSingleThreadExecutor());
107+
108+
assertThat(grpcContainer.grpcServer())
109+
.isNotNull();
110+
}
111+
102112
@Test
103113
@DisplayName("shutdown server")
104114
void shutdownItself() throws IOException {

version.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
/**
3535
* Version of this library.
3636
*/
37-
val coreJava = "1.7.4"
37+
val coreJava = "1.7.5"
3838

3939
/**
4040
* Versions of the Spine libraries that `core-java` depends on.

0 commit comments

Comments
 (0)