parent
033548a760
commit
73d30dd875
|
@ -497,10 +497,12 @@ Annotated, HTTP exchange methods support the following return values:
|
||||||
TIP: You can also use any other async or reactive types registered in the
|
TIP: You can also use any other async or reactive types registered in the
|
||||||
`ReactiveAdapterRegistry`.
|
`ReactiveAdapterRegistry`.
|
||||||
|
|
||||||
TIP: For non-reactive types, blocking from a reactive publisher is performed
|
By default, the behavior of HTTP service methods with synchronous (blocking) method
|
||||||
under the hood by the framework. By default, it is done without a timeout.
|
signature depends on connection and timeout settings of the underlying HTTP client.
|
||||||
You can set a timeout for blocking by calling `blockTimeout(Duration blockTimeout)`
|
`HttpServiceProxyFactory.Builder` does expose a `blockTimeout` option that also lets you
|
||||||
on `HttpServiceProxyFactory.Builder`.
|
configure the maximum time to block for a response, but we recommend configuring timeout
|
||||||
|
values directly on the underlying HTTP client, which likely provides more control over
|
||||||
|
such settings.
|
||||||
|
|
||||||
|
|
||||||
[[rest-http-interface-exceptions]]
|
[[rest-http-interface-exceptions]]
|
||||||
|
|
|
@ -1064,7 +1064,9 @@ Annotated, RSocket exchange methods support return values that are concrete valu
|
||||||
any producer of value(s) that can be adapted to a Reactive Streams `Publisher` via
|
any producer of value(s) that can be adapted to a Reactive Streams `Publisher` via
|
||||||
`ReactiveAdapterRegistry`.
|
`ReactiveAdapterRegistry`.
|
||||||
|
|
||||||
TIP: For non-reactive types, blocking from a reactive publisher is performed
|
By default, the behavior of RSocket service methods with synchronous (blocking) method
|
||||||
under the hood by the framework. By default, it is done without a timeout.
|
signature depends on response timeout settings of the underlying RSocket `ClientTransport`
|
||||||
You can set a timeout for blocking by calling `blockTimeout(Duration blockTimeout)`
|
as well as RSocket keep-alive settings. `RSocketServiceProxyFactory.Builder` does expose a
|
||||||
on `RSocketServiceProxyFactory.Builder`.
|
`blockTimeout` option that also lets you configure the maximum time to block for a response,
|
||||||
|
but we recommend configuring timeout values at the RSocket level for more control.
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,7 @@ final class RSocketServiceMethod {
|
||||||
this.parameters = initMethodParameters(method);
|
this.parameters = initMethodParameters(method);
|
||||||
this.argumentResolvers = argumentResolvers;
|
this.argumentResolvers = argumentResolvers;
|
||||||
this.route = initRoute(method, containingClass, rsocketRequester.strategies(), embeddedValueResolver);
|
this.route = initRoute(method, containingClass, rsocketRequester.strategies(), embeddedValueResolver);
|
||||||
this.responseFunction = initResponseFunction(
|
this.responseFunction = initResponseFunction(rsocketRequester, method, reactiveRegistry, blockTimeout);
|
||||||
rsocketRequester, method, reactiveRegistry, blockTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MethodParameter[] initMethodParameters(Method method) {
|
private static MethodParameter[] initMethodParameters(Method method) {
|
||||||
|
@ -163,11 +162,16 @@ final class RSocketServiceMethod {
|
||||||
if (reactiveAdapter != null) {
|
if (reactiveAdapter != null) {
|
||||||
return reactiveAdapter.fromPublisher(responsePublisher);
|
return reactiveAdapter.fromPublisher(responsePublisher);
|
||||||
}
|
}
|
||||||
return (blockForOptional ?
|
if (blockForOptional) {
|
||||||
(blockTimeout != null ? ((Mono<?>) responsePublisher).blockOptional(blockTimeout) :
|
return (blockTimeout != null ?
|
||||||
((Mono<?>) responsePublisher).blockOptional()) :
|
((Mono<?>) responsePublisher).blockOptional(blockTimeout) :
|
||||||
(blockTimeout != null ? ((Mono<?>) responsePublisher).block(blockTimeout) :
|
((Mono<?>) responsePublisher).blockOptional());
|
||||||
((Mono<?>) responsePublisher).block()));
|
}
|
||||||
|
else {
|
||||||
|
return (blockTimeout != null ?
|
||||||
|
((Mono<?>) responsePublisher).block(blockTimeout) :
|
||||||
|
((Mono<?>) responsePublisher).block());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,14 +188,17 @@ public final class RSocketServiceProxyFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure how long to wait for a response for an HTTP service method
|
* Configure how long to block for the response of an RSocket service method
|
||||||
* with a synchronous (blocking) method signature.
|
* with a synchronous (blocking) method signature.
|
||||||
* <p>By default this is {@code null},
|
* <p>By default this is not set, in which case the behavior depends on
|
||||||
* in which case means blocking on publishers is done without a timeout.
|
* connection and response timeout settings of the underlying RSocket
|
||||||
|
* {@code ClientTransport} as well as RSocket keep-alive settings.
|
||||||
|
* We recommend configuring timeout values at the RSocket level which
|
||||||
|
* provides more control.
|
||||||
* @param blockTimeout the timeout value
|
* @param blockTimeout the timeout value
|
||||||
* @return this same builder instance
|
* @return this same builder instance
|
||||||
*/
|
*/
|
||||||
public Builder blockTimeout(Duration blockTimeout) {
|
public Builder blockTimeout(@Nullable Duration blockTimeout) {
|
||||||
this.blockTimeout = blockTimeout;
|
this.blockTimeout = blockTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -208,8 +211,7 @@ public final class RSocketServiceProxyFactory {
|
||||||
|
|
||||||
return new RSocketServiceProxyFactory(
|
return new RSocketServiceProxyFactory(
|
||||||
this.rsocketRequester, initArgumentResolvers(),
|
this.rsocketRequester, initArgumentResolvers(),
|
||||||
this.embeddedValueResolver, this.reactiveAdapterRegistry,
|
this.embeddedValueResolver, this.reactiveAdapterRegistry, this.blockTimeout);
|
||||||
this.blockTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RSocketServiceArgumentResolver> initArgumentResolvers() {
|
private List<RSocketServiceArgumentResolver> initArgumentResolvers() {
|
||||||
|
|
|
@ -123,15 +123,13 @@ final class HttpServiceMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int index = i;
|
int index = i;
|
||||||
Assert.state(resolved, () -> formatArgumentError(this.parameters[index], "No suitable resolver"));
|
Assert.state(resolved, () ->
|
||||||
|
"Could not resolve parameter [" + this.parameters[index].getParameterIndex() + "] in " +
|
||||||
|
this.parameters[index].getExecutable().toGenericString() +
|
||||||
|
(StringUtils.hasText("No suitable resolver") ? ": " + "No suitable resolver" : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatArgumentError(MethodParameter param, String message) {
|
|
||||||
return "Could not resolve parameter [" + param.getParameterIndex() + "] in " +
|
|
||||||
param.getExecutable().toGenericString() + (StringUtils.hasText(message) ? ": " + message : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link HttpRequestValues} with values extracted from the type
|
* Factory for {@link HttpRequestValues} with values extracted from the type
|
||||||
|
@ -277,17 +275,6 @@ final class HttpServiceMethod {
|
||||||
@Nullable ReactiveAdapter returnTypeAdapter,
|
@Nullable ReactiveAdapter returnTypeAdapter,
|
||||||
boolean blockForOptional, @Nullable Duration blockTimeout) {
|
boolean blockForOptional, @Nullable Duration blockTimeout) {
|
||||||
|
|
||||||
private ResponseFunction(
|
|
||||||
Function<HttpRequestValues, Publisher<?>> responseFunction,
|
|
||||||
@Nullable ReactiveAdapter returnTypeAdapter,
|
|
||||||
boolean blockForOptional, Duration blockTimeout) {
|
|
||||||
|
|
||||||
this.responseFunction = responseFunction;
|
|
||||||
this.returnTypeAdapter = returnTypeAdapter;
|
|
||||||
this.blockForOptional = blockForOptional;
|
|
||||||
this.blockTimeout = blockTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Object execute(HttpRequestValues requestValues) {
|
public Object execute(HttpRequestValues requestValues) {
|
||||||
|
|
||||||
|
@ -297,11 +284,16 @@ final class HttpServiceMethod {
|
||||||
return this.returnTypeAdapter.fromPublisher(responsePublisher);
|
return this.returnTypeAdapter.fromPublisher(responsePublisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this.blockForOptional ?
|
if (this.blockForOptional) {
|
||||||
(this.blockTimeout != null ? ((Mono<?>) responsePublisher).blockOptional(this.blockTimeout) :
|
return (this.blockTimeout != null ?
|
||||||
((Mono<?>) responsePublisher).blockOptional()) :
|
((Mono<?>) responsePublisher).blockOptional(this.blockTimeout) :
|
||||||
(this.blockTimeout != null ? ((Mono<?>) responsePublisher).block(this.blockTimeout) :
|
((Mono<?>) responsePublisher).blockOptional());
|
||||||
((Mono<?>) responsePublisher).block()));
|
}
|
||||||
|
else {
|
||||||
|
return (this.blockTimeout != null ?
|
||||||
|
((Mono<?>) responsePublisher).block(this.blockTimeout) :
|
||||||
|
((Mono<?>) responsePublisher).block());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,7 +302,7 @@ final class HttpServiceMethod {
|
||||||
*/
|
*/
|
||||||
public static ResponseFunction create(
|
public static ResponseFunction create(
|
||||||
HttpClientAdapter client, Method method, ReactiveAdapterRegistry reactiveRegistry,
|
HttpClientAdapter client, Method method, ReactiveAdapterRegistry reactiveRegistry,
|
||||||
Duration blockTimeout) {
|
@Nullable Duration blockTimeout) {
|
||||||
|
|
||||||
MethodParameter returnParam = new MethodParameter(method, -1);
|
MethodParameter returnParam = new MethodParameter(method, -1);
|
||||||
Class<?> returnType = returnParam.getParameterType();
|
Class<?> returnType = returnParam.getParameterType();
|
||||||
|
|
|
@ -207,14 +207,16 @@ public final class HttpServiceProxyFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure how long to wait for a response for an HTTP service method
|
* Configure how long to block for the response of an HTTP service method
|
||||||
* with a synchronous (blocking) method signature.
|
* with a synchronous (blocking) method signature.
|
||||||
* <p>By default this is {@code null},
|
* <p>By default this is not set, in which case the behavior depends on
|
||||||
* in which case means blocking on publishers is done without a timeout.
|
* connection and request timeout settings of the underlying HTTP client.
|
||||||
|
* We recommend configuring timeout values directly on the underlying HTTP
|
||||||
|
* client, which provides more control over such settings.
|
||||||
* @param blockTimeout the timeout value
|
* @param blockTimeout the timeout value
|
||||||
* @return this same builder instance
|
* @return this same builder instance
|
||||||
*/
|
*/
|
||||||
public Builder blockTimeout(Duration blockTimeout) {
|
public Builder blockTimeout(@Nullable Duration blockTimeout) {
|
||||||
this.blockTimeout = blockTimeout;
|
this.blockTimeout = blockTimeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -227,8 +229,7 @@ public final class HttpServiceProxyFactory {
|
||||||
|
|
||||||
return new HttpServiceProxyFactory(
|
return new HttpServiceProxyFactory(
|
||||||
this.clientAdapter, initArgumentResolvers(),
|
this.clientAdapter, initArgumentResolvers(),
|
||||||
this.embeddedValueResolver, this.reactiveAdapterRegistry,
|
this.embeddedValueResolver, this.reactiveAdapterRegistry, this.blockTimeout);
|
||||||
this.blockTimeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HttpServiceArgumentResolver> initArgumentResolvers() {
|
private List<HttpServiceArgumentResolver> initArgumentResolvers() {
|
||||||
|
|
Loading…
Reference in New Issue