Skip to content

Commit

Permalink
Synchronize the calls subscription observer (underlying `ServerCallIm…
Browse files Browse the repository at this point in the history
…pl` isn't thread-safe).

Allow to set the `Executor` for `GrpcContainer`.
Bump the library version to `1.7.5`.
  • Loading branch information
armiol committed Jul 26, 2021
1 parent 69dd272 commit 0908adf
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 31 deletions.
32 changes: 16 additions & 16 deletions license-report.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


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

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


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).
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).




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

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


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).
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).




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

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


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).
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).




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

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


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).
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).




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

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


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).
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).




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

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


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).
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).




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

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


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).
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).




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

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


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).
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).
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ all modules and does not describe the project structure per-subproject.

<groupId>io.spine</groupId>
<artifactId>spine-core-java</artifactId>
<version>1.7.1</version>
<version>1.7.5</version>

<inceptionYear>2015</inceptionYear>

Expand Down
84 changes: 74 additions & 10 deletions server/src/main/java/io/spine/server/GrpcContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
import java.io.IOException;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;

/**
* Wrapping container for gRPC server.
Expand All @@ -54,6 +56,7 @@
*
* <p>Uses {@link ServerServiceDefinition}s of each service.
*/
@SuppressWarnings("ClassWithTooManyMethods") /* Extensive configuration. */
public final class GrpcContainer {

private static final String SERVER_NOT_STARTED_MSG =
Expand Down Expand Up @@ -128,15 +131,41 @@ public Optional<String> serverName() {
/**
* Starts the service.
*
* <p>A gRPC-default executor is used for the server routines. I.e., in-process gRPC server
* is going to run on top of a {@linkplain ServerBuilder#directExecutor() direct executor},
* and a server exposed at a port will run on top of a shared cached thread pool.
*
* <p>See the {@link ServerBuilder} Javadocs corresponding to the current gRPC version
* for more details.
*
* @throws IOException
* if unable to bind
*/
public void start() throws IOException {
checkState(grpcServer == null, "gRPC server is started already.");
grpcServer = createGrpcServer();
checkNotStarted();
grpcServer = createGrpcServer(/* ...with a gRPC-default executor. */ null);
grpcServer.start();
}

/**
* Starts the service on top of the given {@code Executor}.
*
* @param executor
* an executor to use for gRPC server
* @throws IOException
* if unable to bind
*/
public void start(Executor executor) throws IOException {
checkNotStarted();
checkNotNull(executor, "Executor must not be `null`.");
grpcServer = createGrpcServer(executor);
grpcServer.start();
}

private void checkNotStarted() {
checkState(grpcServer == null, "gRPC server is started already.");
}

/**
* Returns {@code true} if the server is shut down or was not started at all,
* {@code false} otherwise.
Expand Down Expand Up @@ -238,30 +267,64 @@ public void addShutdownHook() {
.addShutdownHook(new Thread(shutdownCallback()));
}

private Server createGrpcServer() {
/**
* Creates a gRPC server which uses a specified executor.
*
* <p>If {@code null} is passed, a default behavior of the gRPC {@link ServerBuilder}
* is applied.
*
* @param executor
* executor to use for the gRPC server
*/
private Server createGrpcServer(@Nullable Executor executor) {
if (injectedServer != null) {
return injectedServer;
}
ServerBuilder builder = createServerBuilder();
ServerBuilder<?> builder = createServerBuilder(executor);
for (ServerServiceDefinition service : services) {
builder.addService(service);
}
return builder.build();
}

private ServerBuilder createServerBuilder() {
ServerBuilder result =
/**
* Creates a builder of the gRPC server with the provided executor.
*
* <p>If {@code null} is passed, a default behavior of the gRPC {@link ServerBuilder}
* is applied.
*
* @param executor
* executor to configure for the created builder
*/
private ServerBuilder<?> createServerBuilder(@Nullable Executor executor) {
ServerBuilder<?> result =
serverName == null
? ServerBuilder.forPort(checkNotNull(port))
: InProcessServerBuilder.forName(serverName)
.directExecutor();
? builderAtPort(requireNonNull(port), executor)
: inProcessBuilder(serverName, executor);
return result;
}

private static ServerBuilder<?> inProcessBuilder(String name, @Nullable Executor executor) {
InProcessServerBuilder builder = InProcessServerBuilder.forName(name);
builder = executor == null
? builder.directExecutor()
: builder.executor(executor);
return builder;
}

private static ServerBuilder<?> builderAtPort(Integer port, @Nullable Executor executor) {
ServerBuilder<?> builder = ServerBuilder.forPort(port);
builder = executor == null
? builder
: builder.executor(executor);
return builder;
}

/**
* Injects a server to this container.
*
* <p>All calls to {@link #createGrpcServer()} will resolve to the given server instance.
* <p>All calls to {@link #createGrpcServer(Executor)} will resolve to the given server
* instance.
*
* <p>A test-only method.
*/
Expand Down Expand Up @@ -356,6 +419,7 @@ public Builder removeService(ServerServiceDefinition service) {

/**
* Obtains the services already added to the builder.
*
* @deprecated please use {@link #services()}.
*/
@Deprecated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ public interface SubscriptionCallback extends Consumer<SubscriptionUpdate> {
*/
static SubscriptionCallback forwardingTo(StreamObserver<SubscriptionUpdate> observer) {
return update -> {
checkNotNull(update);
observer.onNext(update);
synchronized (observer) {
checkNotNull(update);
observer.onNext(update);
}
};
}
}
12 changes: 11 additions & 1 deletion server/src/test/java/io/spine/server/GrpcContainerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static io.spine.testing.TestValues.randomString;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

@DisplayName("GrpcContainer should")
@DisplayName("`GrpcContainer` should")
class GrpcContainerTest {

private GrpcContainer grpcContainer;
Expand Down Expand Up @@ -99,6 +100,15 @@ void startServer() throws IOException {
.isNotNull();
}

@Test
@DisplayName("start server with the given `Executor`")
void startServerWithExecutor() throws IOException {
grpcContainer.start(newSingleThreadExecutor());

assertThat(grpcContainer.grpcServer())
.isNotNull();
}

@Test
@DisplayName("shutdown server")
void shutdownItself() throws IOException {
Expand Down
2 changes: 1 addition & 1 deletion version.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
/**
* Version of this library.
*/
val coreJava = "1.7.4"
val coreJava = "1.7.5"

/**
* Versions of the Spine libraries that `core-java` depends on.
Expand Down

0 comments on commit 0908adf

Please sign in to comment.