forked from grpc/grpc-java
/
InProcessServerBuilder.java
177 lines (164 loc) · 6.36 KB
/
InProcessServerBuilder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* Copyright 2015 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.inprocess;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Preconditions;
import io.grpc.Deadline;
import io.grpc.ExperimentalApi;
import io.grpc.ServerStreamTracer;
import io.grpc.internal.AbstractServerImplBuilder;
import io.grpc.internal.FixedObjectPool;
import io.grpc.internal.GrpcUtil;
import io.grpc.internal.ObjectPool;
import io.grpc.internal.SharedResourcePool;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Builder for a server that services in-process requests. Clients identify the in-process server by
* its name.
*
* <p>The server is intended to be fully-featured, high performance, and useful in testing.
*
* <h3>Using JUnit TestRule</h3>
* The class "GrpcServerRule" (from "grpc-java/testing") is a JUnit TestRule that
* creates a {@link InProcessServer} and a {@link io.grpc.ManagedChannel ManagedChannel}. This
* test rule contains the boilerplate code shown below. The classes "HelloWorldServerTest" and
* "HelloWorldClientTest" (from "grpc-java/examples") demonstrate basic usage.
*
* <h3>Usage example</h3>
* <h4>Server and client channel setup</h4>
* <pre>
* String uniqueName = InProcessServerBuilder.generateName();
* Server server = InProcessServerBuilder.forName(uniqueName)
* .directExecutor() // directExecutor is fine for unit tests
* .addService(/* your code here */)
* .build().start();
* ManagedChannel channel = InProcessChannelBuilder.forName(uniqueName)
* .directExecutor()
* .build();
* </pre>
*
* <h4>Usage in tests</h4>
* The channel can be used normally. A blocking stub example:
* <pre>
* TestServiceGrpc.TestServiceBlockingStub blockingStub =
* TestServiceGrpc.newBlockingStub(channel);
* </pre>
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1783")
public final class InProcessServerBuilder
extends AbstractServerImplBuilder<InProcessServerBuilder> {
/**
* Create a server builder that will bind with the given name.
*
* @param name the identity of the server for clients to connect to
* @return a new builder
*/
public static InProcessServerBuilder forName(String name) {
return new InProcessServerBuilder(name);
}
/**
* Always fails. Call {@link #forName} instead.
*/
public static InProcessServerBuilder forPort(int port) {
throw new UnsupportedOperationException("call forName() instead");
}
/**
* Generates a new server name that is unique each time.
*/
public static String generateName() {
return UUID.randomUUID().toString();
}
final String name;
int maxInboundMetadataSize = Integer.MAX_VALUE;
ObjectPool<ScheduledExecutorService> schedulerPool =
SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE);
private InProcessServerBuilder(String name) {
this.name = Preconditions.checkNotNull(name, "name");
// In-process transport should not record its traffic to the stats module.
// https://github.com/grpc/grpc-java/issues/2284
setStatsRecordStartedRpcs(false);
setStatsRecordFinishedRpcs(false);
// Disable handshake timeout because it is unnecessary, and can trigger Thread creation that can
// break some environments (like tests).
handshakeTimeout(Long.MAX_VALUE, TimeUnit.SECONDS);
}
/**
* Provides a custom scheduled executor service.
*
* <p>It's an optional parameter. If the user has not provided a scheduled executor service when
* the channel is built, the builder will use a static cached thread pool.
*
* @return this
*
* @since 1.11.0
*/
public InProcessServerBuilder scheduledExecutorService(
ScheduledExecutorService scheduledExecutorService) {
schedulerPool = new FixedObjectPool<>(
checkNotNull(scheduledExecutorService, "scheduledExecutorService"));
return this;
}
/**
* Provides a custom deadline ticker that this server will use to create incoming {@link
* Deadline}s.
*
* <p>This is intended for unit tests that fake out the clock. You should also have a fake {@link
* ScheduledExecutorService} whose clock is synchronized with this ticker and set it to {@link
* #scheduledExecutorService}. DO NOT use this in production.
*
* @return this
* @see Deadline#after(long, TimeUnit, Deadline.Ticker)
*
* @since 1.24.0
*/
public InProcessServerBuilder deadlineTicker(Deadline.Ticker ticker) {
setDeadlineTicker(ticker);
return this;
}
/**
* Sets the maximum size of metadata allowed to be received. {@code Integer.MAX_VALUE} disables
* the enforcement. Defaults to no limit ({@code Integer.MAX_VALUE}).
*
* <p>There is potential for performance penalty when this setting is enabled, as the Metadata
* must actually be serialized. Since the current implementation of Metadata pre-serializes, it's
* currently negligible. But Metadata is free to change its implementation.
*
* @param bytes the maximum size of received metadata
* @return this
* @throws IllegalArgumentException if bytes is non-positive
* @since 1.17.0
*/
@Override
public InProcessServerBuilder maxInboundMetadataSize(int bytes) {
Preconditions.checkArgument(bytes > 0, "maxInboundMetadataSize must be > 0");
this.maxInboundMetadataSize = bytes;
return this;
}
@Override
protected List<InProcessServer> buildTransportServers(
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
return Collections.singletonList(new InProcessServer(this, streamTracerFactories));
}
@Override
public InProcessServerBuilder useTransportSecurity(File certChain, File privateKey) {
throw new UnsupportedOperationException("TLS not supported in InProcessServer");
}
}