Use mutation methods for stub reconfiguration.

This makes the reconfiguration code more concise.

- Remove configureNewStub().
- Add mutation methods withDeadlineNanoTime(), withChannel() etc that
  returns the reconfigured stub.
This commit is contained in:
Kun Zhang 2015-07-22 16:52:28 -07:00
parent afdbe19937
commit 60cf5eb5da
4 changed files with 44 additions and 88 deletions

View File

@ -588,9 +588,7 @@ public abstract class AbstractTransportTest {
public void sendsTimeoutHeader() {
long configuredTimeoutMinutes = 100;
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel)
.configureNewStub()
.setDeadlineAfter(configuredTimeoutMinutes, TimeUnit.MINUTES)
.build();
.withDeadlineAfter(configuredTimeoutMinutes, TimeUnit.MINUTES);
stub.emptyCall(Empty.getDefaultInstance());
long transferredTimeoutMinutes = TimeUnit.MICROSECONDS.toMinutes(
requestHeadersCapture.get().get(ChannelImpl.TIMEOUT_KEY));
@ -607,9 +605,8 @@ public abstract class AbstractTransportTest {
// warm up the channel and JVM
blockingStub.emptyCall(Empty.getDefaultInstance());
TestServiceGrpc.newBlockingStub(channel)
.configureNewStub()
.setDeadlineAfter(50, TimeUnit.MILLISECONDS)
.build().emptyCall(Empty.getDefaultInstance());
.withDeadlineAfter(50, TimeUnit.MILLISECONDS)
.emptyCall(Empty.getDefaultInstance());
}
@Test(timeout = 10000)
@ -618,9 +615,7 @@ public abstract class AbstractTransportTest {
// warm up the channel and JVM
blockingStub.emptyCall(Empty.getDefaultInstance());
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel)
.configureNewStub()
.setDeadlineAfter(10, TimeUnit.MILLISECONDS)
.build();
.withDeadlineAfter(10, TimeUnit.MILLISECONDS);
try {
stub.emptyCall(Empty.getDefaultInstance());
fail("Expected deadline to be exceeded");
@ -647,9 +642,8 @@ public abstract class AbstractTransportTest {
.build();
StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
TestServiceGrpc.newStub(channel)
.configureNewStub()
.setDeadlineAfter(30, TimeUnit.MILLISECONDS)
.build().streamingOutputCall(request, recorder);
.withDeadlineAfter(30, TimeUnit.MILLISECONDS)
.streamingOutputCall(request, recorder);
recorder.awaitCompletion();
assertEquals(Status.DEADLINE_EXCEEDED, Status.fromThrowable(recorder.getError()));
assertNotEquals(0, recorder.getValues().size());
@ -723,9 +717,8 @@ public abstract class AbstractTransportTest {
GoogleCredentials credentials =
(ServiceAccountCredentials) GoogleCredentials.fromStream(credentialsStream);
credentials = credentials.createScoped(Arrays.<String>asList(authScope));
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub.configureNewStub()
.addInterceptor(new ClientAuthInterceptor(credentials, testServiceExecutor))
.build();
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub
.withInterceptors(new ClientAuthInterceptor(credentials, testServiceExecutor));
final SimpleRequest request = SimpleRequest.newBuilder()
.setFillUsername(true)
.setFillOauthScope(true)
@ -756,9 +749,8 @@ public abstract class AbstractTransportTest {
/** Sends a large unary rpc with compute engine credentials. */
public void computeEngineCreds(String serviceAccount, String oauthScope) throws Exception {
ComputeEngineCredentials credentials = new ComputeEngineCredentials();
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub.configureNewStub()
.addInterceptor(new ClientAuthInterceptor(credentials, testServiceExecutor))
.build();
TestServiceGrpc.TestServiceBlockingStub stub = blockingStub
.withInterceptors(new ClientAuthInterceptor(credentials, testServiceExecutor));
final SimpleRequest request = SimpleRequest.newBuilder()
.setFillUsername(true)
.setFillOauthScope(true)

View File

@ -87,8 +87,7 @@ public class StubConfigTest {
TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel);
assertNull(stub.getCallOptions().getDeadlineNanoTime());
// Reconfigure it
TestServiceGrpc.TestServiceBlockingStub reconfiguredStub =
stub.configureNewStub().setDeadlineNanoTime(2L).build();
TestServiceGrpc.TestServiceBlockingStub reconfiguredStub = stub.withDeadlineNanoTime(2L);
// New altered config
assertEquals(2L, (long) reconfiguredStub.getCallOptions().getDeadlineNanoTime());
// Default config unchanged
@ -102,7 +101,7 @@ public class StubConfigTest {
SimpleRequest request = SimpleRequest.getDefaultInstance();
stub.unaryCall(request, responseObserver);
verify(channel).newCall(same(TestServiceGrpc.METHOD_UNARY_CALL), same(options1));
stub = stub.configureNewStub().setDeadlineNanoTime(2L).build();
stub = stub.withDeadlineNanoTime(2L);
CallOptions options2 = stub.getCallOptions();
assertNotSame(options1, options2);
stub.unaryCall(request, responseObserver);

View File

@ -36,8 +36,6 @@ import io.grpc.Channel;
import io.grpc.ClientInterceptor;
import io.grpc.ClientInterceptors;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
@ -74,13 +72,6 @@ public abstract class AbstractStub<S extends AbstractStub<?>> {
this.callOptions = callOptions;
}
/**
* Creates a builder for reconfiguring the stub.
*/
public StubConfigBuilder configureNewStub() {
return new StubConfigBuilder();
}
/**
* The underlying channel of the stub.
*/
@ -104,63 +95,38 @@ public abstract class AbstractStub<S extends AbstractStub<?>> {
protected abstract S build(Channel channel, CallOptions callOptions);
/**
* Utility class for (re) configuring the operations in a stub.
* Returns a new stub with an absolute deadline in nanoseconds in the clock as per {@link
* System#nanoTime()}.
*
* <p>This is mostly used for propagating an existing deadline. {@link #withDeadlineAfter} is the
* recommended way of setting a new deadline,
*
* @param deadlineNanoTime nanoseconds in the clock as per {@link System#nanoTime()}
*/
public class StubConfigBuilder {
public final S withDeadlineNanoTime(@Nullable Long deadlineNanoTime) {
return build(channel, callOptions.withDeadlineNanoTime(deadlineNanoTime));
}
private final List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
private CallOptions callOptions = AbstractStub.this.callOptions;
private Channel stubChannel;
/**
* Returns a new stub with a deadline that is after the given {@code duration} from now.
*
* @see CallOptions#withDeadlineAfter
*/
public final S withDeadlineAfter(long duration, TimeUnit unit) {
return build(channel, callOptions.withDeadlineAfter(duration, unit));
}
private StubConfigBuilder() {
this.stubChannel = AbstractStub.this.channel;
}
/**
* Returns a new stub that uses the given channel.
*/
public final S withChannel(Channel newChannel) {
return build(newChannel, callOptions);
}
/**
* Sets an absolute deadline in nanoseconds in the clock as per {@link System#nanoTime()}.
*
* <p>This is mostly used for propagating an existing deadline. {@link #setDeadlineAfter} is the
* recommended way of setting a new deadline,
*
* @param deadlineNanoTime nanoseconds in the clock as per {@link System#nanoTime()}
*/
public StubConfigBuilder setDeadlineNanoTime(@Nullable Long deadlineNanoTime) {
callOptions = callOptions.withDeadlineNanoTime(deadlineNanoTime);
return this;
}
/**
* Sets a deadline that is after the given {@code duration} from now.
*
* @see CallOptions#withDeadlineAfter
*/
public StubConfigBuilder setDeadlineAfter(long duration, TimeUnit unit) {
callOptions = callOptions.withDeadlineAfter(duration, unit);
return this;
}
/**
* Set the channel to be used by the stub.
*/
public StubConfigBuilder setChannel(Channel channel) {
this.stubChannel = channel;
return this;
}
/**
* Adds a client interceptor to be attached to the channel of the reconfigured stub.
*/
public StubConfigBuilder addInterceptor(ClientInterceptor interceptor) {
interceptors.add(interceptor);
return this;
}
/**
* Create a new stub with the configurations made on this builder.
*/
public S build() {
return AbstractStub.this.build(
ClientInterceptors.intercept(stubChannel, interceptors), callOptions);
}
/**
* Returns a new stub that has the given interceptors attached to the underlying channel.
*/
public final S withInterceptors(ClientInterceptor... interceptors) {
return build(ClientInterceptors.intercept(channel, interceptors), callOptions);
}
}

View File

@ -59,8 +59,7 @@ public class MetadataUtils {
public static <T extends AbstractStub> T attachHeaders(
T stub,
final Metadata.Headers extraHeaders) {
return (T) stub.configureNewStub().addInterceptor(
newAttachHeadersInterceptor(extraHeaders)).build();
return (T) stub.withInterceptors(newAttachHeadersInterceptor(extraHeaders));
}
/**
@ -100,8 +99,8 @@ public class MetadataUtils {
T stub,
AtomicReference<Metadata.Headers> headersCapture,
AtomicReference<Metadata.Trailers> trailersCapture) {
return (T) stub.configureNewStub().addInterceptor(
newCaptureMetadataInterceptor(headersCapture, trailersCapture)).build();
return (T) stub.withInterceptors(
newCaptureMetadataInterceptor(headersCapture, trailersCapture));
}
/**