Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MultiAddressClientBuilder execution strategy control #2166

Merged
merged 64 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
dc260f4
`MultiAddressClientBuilder` execution strategy control
bondolo Jan 21, 2022
20cec2a
fixes ClientEffectiveStrategyTest for basic Single and Multi builders
bondolo Apr 1, 2022
65ceda1
fixes ClientEffectiveStrategyTest for multi builder with initializer
bondolo Apr 1, 2022
61814d1
pre-final cleanup
bondolo Apr 1, 2022
09e2ea9
documentation improvements
bondolo Apr 1, 2022
db7f892
Handle single address builder overrides of offloadNone()
bondolo Apr 7, 2022
6392624
checkstyle nits
bondolo Apr 7, 2022
24d6216
combine client api test cases
bondolo Apr 7, 2022
dd7a88d
review feedback
bondolo Apr 13, 2022
074584a
remove DefaultClientGroup changes from PR
bondolo Apr 13, 2022
2be80b6
test cleanup
bondolo Apr 13, 2022
b2dbc55
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Apr 14, 2022
4ade1dc
move FilterableClientToClient back
bondolo Apr 14, 2022
b0d2c3e
additional review feedback
bondolo Apr 15, 2022
0f7c444
test cleanup
bondolo Apr 15, 2022
3e151d6
test cleanup
bondolo Apr 15, 2022
035fdd3
fix multi-address builder strategy computation
bondolo Apr 15, 2022
030833a
checkstyle nit
bondolo Apr 15, 2022
5cb3a92
more test simplification
bondolo Apr 15, 2022
efba308
even more review feedback
bondolo Apr 15, 2022
e541a50
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Apr 18, 2022
47ec7f8
test improvements and suggestions from Idel's review
bondolo Apr 18, 2022
8f0819d
allow send offload to execute on application thread
bondolo Apr 19, 2022
330824e
allow send offload to execute on application thread
bondolo Apr 19, 2022
97453d9
restore second request
bondolo Apr 19, 2022
c7d00bd
enhance visibility in tests
idelpivnitskiy Apr 20, 2022
522e7e6
more debugging
idelpivnitskiy Apr 20, 2022
36def49
more debugging 2
idelpivnitskiy Apr 20, 2022
9e6530d
add timestamps
idelpivnitskiy Apr 21, 2022
90d1728
Merge branch 'apple:main' into multiaddress-initializer-strategy
bondolo Apr 21, 2022
2c7e1df
change order or ClientApi
idelpivnitskiy Apr 21, 2022
5d95094
only allow application thread if not offloading
bondolo Apr 20, 2022
be76acf
use local for simplification
bondolo Apr 21, 2022
1419244
revert unintended changes
bondolo Apr 21, 2022
60040b2
capture where context map created and assigned
idelpivnitskiy Apr 22, 2022
efaa5a5
capture requestContext id too
idelpivnitskiy Apr 22, 2022
9d6e6a4
Remove ExecutionMode.CONCURRENT
idelpivnitskiy Apr 22, 2022
ef49a05
Revert intermediate debugging
idelpivnitskiy Apr 23, 2022
d670415
Remove intermediate debug logging
idelpivnitskiy Apr 23, 2022
a33671b
reorder client api
idelpivnitskiy Apr 23, 2022
312c836
revert `ExecutionMode.CONCURRENT`
idelpivnitskiy Apr 23, 2022
34a468d
small refactoring
idelpivnitskiy Apr 23, 2022
3079781
small refactoring 2
idelpivnitskiy Apr 23, 2022
f591a1c
small refactoring 3
idelpivnitskiy Apr 23, 2022
79b922c
rename filter, add javadoc to clarify its behavior
idelpivnitskiy Apr 23, 2022
da80a7e
Add assertion checking for conversion reducing offloading
bondolo Apr 25, 2022
b45b45d
improve executionStrategy() documentation
bondolo Apr 27, 2022
09e63bd
improved javadoc
bondolo Apr 29, 2022
d5a83f0
documentation refinement for discussion
bondolo May 18, 2022
acd2535
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 6, 2022
dfa383b
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 7, 2022
8380d2a
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 7, 2022
cead445
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 8, 2022
945762a
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 8, 2022
10da51b
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 9, 2022
7652859
Use current strategy for merging with offloadNone()
bondolo Jun 9, 2022
c52950c
adjust everything to current "builder takes precedece" rule
bondolo Jun 10, 2022
aebccc9
documentation matches behaviour and fix multi-offloadNone overrid
bondolo Jun 10, 2022
55c5095
fix javadoc nit
bondolo Jun 10, 2022
239b3aa
remove redundant modification of the request execution strategy
bondolo Jun 10, 2022
b6a4c15
checkstyle nit
bondolo Jun 10, 2022
c385897
remove assertion of incompatible behavior
bondolo Jun 15, 2022
81f818f
Merge branch 'main' into multiaddress-initializer-strategy
bondolo Jun 15, 2022
ee1ba16
final review feedback
bondolo Jun 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,19 @@ public Client get(final Key key) {
try {
client = requireNonNull(clientFactory.apply(key), "Newly created client can not be null");
} catch (Throwable t) {
clientMap.remove(key); // PLACEHOLDER_CLIENT
final boolean removed = clientMap.remove(key, PLACEHOLDER_CLIENT);
assert removed : "Expected to remove PLACEHOLDER_CLIENT";
throw new IllegalArgumentException("Failed to create new client", t);
}

clientMap.put(key, client); // Overwrite PLACEHOLDER_CLIENT
final boolean replaced = clientMap.replace(key, PLACEHOLDER_CLIENT, client);
assert replaced : "Expected to replace PLACEHOLDER_CLIENT";
toSource(client.onClose()).subscribe(new RemoveClientOnClose(key, client));
LOGGER.debug("A new client {} was created", client);

if (closed) {
// group has been closed after a new client was created
if (clientMap.remove(key) != null) { // not closed by closing thread
if (clientMap.remove(key, client)) { // not closed by closing thread
bondolo marked this conversation as resolved.
Show resolved Hide resolved
client.closeAsync().subscribe();
LOGGER.debug("Recently created client {} was removed and closed, group {} closed", client, this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ enum DefaultHttpExecutionStrategy implements HttpExecutionStrategy {
OFFLOAD_SEND_EVENT_STRATEGY(EnumSet.of(OFFLOAD_SEND, OFFLOAD_EVENT)),
OFFLOAD_RECEIVE_META_AND_SEND_EVENT_STRATEGY(EnumSet.of(OFFLOAD_RECEIVE_META, OFFLOAD_SEND, OFFLOAD_EVENT)),
OFFLOAD_RECEIVE_DATA_AND_SEND_EVENT_STRATEGY(EnumSet.of(OFFLOAD_RECEIVE_DATA, OFFLOAD_SEND, OFFLOAD_EVENT)),
OFFLOADD_ALL_REQRESP_EVENT_STRATEGY(
OFFLOAD_ALL_REQRESP_EVENT_STRATEGY(
EnumSet.of(OFFLOAD_RECEIVE_META, OFFLOAD_RECEIVE_DATA, OFFLOAD_SEND, OFFLOAD_EVENT)),

OFFLOAD_CLOSE_STRATEGY(EnumSet.of(OFFLOAD_CLOSE)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,88 +13,83 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.http.netty;
package io.servicetalk.http.api;

import io.servicetalk.concurrent.api.Completable;
import io.servicetalk.concurrent.api.Publisher;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.http.api.BlockingHttpClient;
import io.servicetalk.http.api.BlockingStreamingHttpClient;
import io.servicetalk.http.api.FilterableStreamingHttpClient;
import io.servicetalk.http.api.HttpClient;
import io.servicetalk.http.api.HttpConnectionContext;
import io.servicetalk.http.api.HttpEventKey;
import io.servicetalk.http.api.HttpExecutionContext;
import io.servicetalk.http.api.HttpExecutionStrategy;
import io.servicetalk.http.api.HttpRequestMetaData;
import io.servicetalk.http.api.HttpRequestMethod;
import io.servicetalk.http.api.ReservedBlockingHttpConnection;
import io.servicetalk.http.api.ReservedBlockingStreamingHttpConnection;
import io.servicetalk.http.api.ReservedHttpConnection;
import io.servicetalk.http.api.ReservedStreamingHttpConnection;
import io.servicetalk.http.api.StreamingHttpClient;
import io.servicetalk.http.api.StreamingHttpRequest;
import io.servicetalk.http.api.StreamingHttpResponse;
import io.servicetalk.http.api.StreamingHttpResponseFactory;

import static io.servicetalk.http.api.HttpApiConversions.toBlockingClient;
import static io.servicetalk.http.api.HttpApiConversions.toBlockingStreamingClient;
import static io.servicetalk.http.api.HttpApiConversions.toClient;
import static io.servicetalk.http.api.HttpApiConversions.toReservedBlockingConnection;
import static io.servicetalk.http.api.HttpApiConversions.toReservedBlockingStreamingConnection;
import static io.servicetalk.http.api.HttpApiConversions.toReservedConnection;
import static io.servicetalk.http.api.HttpContextKeys.HTTP_CLIENT_API_KEY;
import static io.servicetalk.http.api.HttpContextKeys.HTTP_EXECUTION_STRATEGY_KEY;

final class FilterableClientToClient implements StreamingHttpClient {
private final FilterableStreamingHttpClient client;
private final HttpExecutionStrategy strategy;
private final DelegatingHttpExecutionContext executionContext;

FilterableClientToClient(FilterableStreamingHttpClient filteredClient, HttpExecutionStrategy strategy) {
client = filteredClient;
this.strategy = strategy;
this.executionContext = new DelegatingHttpExecutionContext(client.executionContext()) {
@Override
public HttpExecutionStrategy executionStrategy() {
return strategy;
}
};
}

@Override
public HttpClient asClient() {
return toClient(this, strategy);
return toClient(this, executionContext.executionStrategy());
}

@Override
public BlockingStreamingHttpClient asBlockingStreamingClient() {
return toBlockingStreamingClient(this, strategy);
return toBlockingStreamingClient(this, executionContext.executionStrategy());
}

@Override
public BlockingHttpClient asBlockingClient() {
return toBlockingClient(this, strategy);
return toBlockingClient(this, executionContext.executionStrategy());
}

@Override
public Single<StreamingHttpResponse> request(final StreamingHttpRequest request) {
return Single.defer(() -> {
request.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY, strategy);
if (null == request.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY,
executionContext().executionStrategy())) {
request.context().put(HTTP_CLIENT_API_KEY, HttpApiConversions.ClientAPI.ASYNC_STREAMING);
}
return client.request(request).shareContextOnSubscribe();
});
}

@Override
public Single<ReservedStreamingHttpConnection> reserveConnection(final HttpRequestMetaData metaData) {
return Single.defer(() -> {
metaData.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY, strategy);
if (null == metaData.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY,
executionContext().executionStrategy())) {
metaData.context().put(HTTP_CLIENT_API_KEY, HttpApiConversions.ClientAPI.ASYNC_STREAMING);
}

return client.reserveConnection(metaData).map(rc -> new ReservedStreamingHttpConnection() {
@Override
public ReservedHttpConnection asConnection() {
return toReservedConnection(this, strategy);
return toReservedConnection(this, executionContext.executionStrategy());
}

@Override
public ReservedBlockingStreamingHttpConnection asBlockingStreamingConnection() {
return toReservedBlockingStreamingConnection(this, strategy);
return toReservedBlockingStreamingConnection(this, executionContext.executionStrategy());
}

@Override
public ReservedBlockingHttpConnection asBlockingConnection() {
return toReservedBlockingConnection(this, strategy);
return toReservedBlockingConnection(this, executionContext.executionStrategy());
}

@Override
Expand All @@ -108,8 +103,10 @@ public Single<StreamingHttpResponse> request(final StreamingHttpRequest request)
// created and hence could have an incorrect default strategy. Doing this makes sure we never call
// the method without strategy just as we do for the regular connection.
return Single.defer(() -> {
request.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY,
FilterableClientToClient.this.strategy);
if (null == request.context().putIfAbsent(HTTP_EXECUTION_STRATEGY_KEY,
FilterableClientToClient.this.executionContext().executionStrategy())) {
request.context().put(HTTP_CLIENT_API_KEY, HttpApiConversions.ClientAPI.ASYNC_STREAMING);
}
return rc.request(request).shareContextOnSubscribe();
});
}
Expand Down Expand Up @@ -159,7 +156,7 @@ public StreamingHttpRequest newRequest(final HttpRequestMethod method, final Str

@Override
public HttpExecutionContext executionContext() {
return client.executionContext();
return executionContext;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,35 @@
import io.servicetalk.http.api.StreamingHttpClientToHttpClient.ReservedStreamingHttpConnectionToReservedHttpConnection;

import static io.servicetalk.http.api.HttpContextKeys.HTTP_EXECUTION_STRATEGY_KEY;
import static io.servicetalk.http.api.StreamingHttpConnectionToBlockingHttpConnection.DEFAULT_BLOCKING_CONNECTION_STRATEGY;
import static io.servicetalk.http.api.StreamingHttpConnectionToBlockingStreamingHttpConnection.DEFAULT_BLOCKING_STREAMING_CONNECTION_STRATEGY;
import static io.servicetalk.http.api.StreamingHttpConnectionToHttpConnection.DEFAULT_ASYNC_CONNECTION_STRATEGY;

/**
* Conversion routines to {@link StreamingHttpService}.
*/
public final class HttpApiConversions {

/**
* The "flavors" of client API available.
*/
public enum ClientAPI {
bondolo marked this conversation as resolved.
Show resolved Hide resolved
BLOCKING_AGGREGATED(DEFAULT_BLOCKING_CONNECTION_STRATEGY),
BLOCKING_STREAMING(DEFAULT_BLOCKING_STREAMING_CONNECTION_STRATEGY),
ASYNC_AGGREGATED(DEFAULT_ASYNC_CONNECTION_STRATEGY),
ASYNC_STREAMING(DefaultHttpExecutionStrategy.OFFLOAD_ALL_REQRESP_EVENT_STRATEGY);

private final HttpExecutionStrategy defaultApiStrategy;

ClientAPI(HttpExecutionStrategy defaultApiStrategy) {
this.defaultApiStrategy = defaultApiStrategy;
}

public HttpExecutionStrategy defaultStrategy() {
return defaultApiStrategy;
}
}

private HttpApiConversions() {
// no instances
}
Expand All @@ -39,6 +62,7 @@ private HttpApiConversions() {
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ReservedHttpConnection toReservedConnection(ReservedStreamingHttpConnection original,
HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -66,6 +90,7 @@ public static ReservedHttpConnection toReservedConnection(ReservedStreamingHttpC
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ReservedBlockingHttpConnection toReservedBlockingConnection(
ReservedStreamingHttpConnection original, HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -94,6 +119,7 @@ public static ReservedBlockingHttpConnection toReservedBlockingConnection(
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ReservedBlockingStreamingHttpConnection toReservedBlockingStreamingConnection(
ReservedStreamingHttpConnection original, HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -122,6 +148,7 @@ public static ReservedBlockingStreamingHttpConnection toReservedBlockingStreamin
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static HttpConnection toConnection(StreamingHttpConnection original,
HttpExecutionStrategyInfluencer influencer) {
Expand All @@ -148,6 +175,7 @@ public static HttpConnection toConnection(StreamingHttpConnection original, Http
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static BlockingHttpConnection toBlockingConnection(StreamingHttpConnection original,
HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -175,6 +203,7 @@ public static BlockingHttpConnection toBlockingConnection(StreamingHttpConnectio
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static BlockingStreamingHttpConnection toBlockingStreamingConnection(
StreamingHttpConnection original, HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -203,6 +232,7 @@ public static BlockingStreamingHttpConnection toBlockingStreamingConnection(
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static HttpClient toClient(StreamingHttpClient original, HttpExecutionStrategyInfluencer influencer) {
return toClient(original, influencer.requiredOffloads());
Expand All @@ -219,6 +249,18 @@ public static HttpClient toClient(StreamingHttpClient original, HttpExecutionStr
return new StreamingHttpClientToHttpClient(original, strategy);
}

/**
* Convert from {@link FilterableStreamingHttpClient} to {@link StreamingHttpClient}.
*
* @param client Original {@link FilterableClientToClient} to convert.
* @param strategy required strategy for the service when invoking the resulting {@link HttpClient}
* @return The conversion result.
*/
public static StreamingHttpClient toStreamingClient(final FilterableStreamingHttpClient client,
bondolo marked this conversation as resolved.
Show resolved Hide resolved
final HttpExecutionStrategy strategy) {
return new FilterableClientToClient(client, strategy);
}

/**
* Convert from {@link StreamingHttpClient} to {@link BlockingHttpClient}.
*
Expand All @@ -228,6 +270,7 @@ public static HttpClient toClient(StreamingHttpClient original, HttpExecutionStr
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static BlockingHttpClient toBlockingClient(StreamingHttpClient original,
HttpExecutionStrategyInfluencer influencer) {
Expand All @@ -254,6 +297,7 @@ public static BlockingHttpClient toBlockingClient(StreamingHttpClient original,
* @return The conversion result.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static BlockingStreamingHttpClient toBlockingStreamingClient(StreamingHttpClient original,
HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -281,6 +325,7 @@ public static BlockingStreamingHttpClient toBlockingStreamingClient(StreamingHtt
* @return {@link ServiceAdapterHolder} containing the service adapted to the streaming programming model.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ServiceAdapterHolder toStreamingHttpService(HttpService service,
HttpExecutionStrategyInfluencer influencer) {
Expand All @@ -307,6 +352,7 @@ public static ServiceAdapterHolder toStreamingHttpService(HttpService service, H
* @return {@link ServiceAdapterHolder} containing the service adapted to the streaming programming model.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ServiceAdapterHolder toStreamingHttpService(BlockingStreamingHttpService service,
HttpExecutionStrategyInfluencer influencer) {
Expand Down Expand Up @@ -334,6 +380,7 @@ public static ServiceAdapterHolder toStreamingHttpService(BlockingStreamingHttpS
* @return {@link ServiceAdapterHolder} containing the service adapted to the streaming programming model.
* @deprecated Use overload with {@link HttpExecutionStrategy} rather than {@link HttpExecutionStrategyInfluencer}
*/
// FIXME: 0.43 - remove deprecated method
@Deprecated
public static ServiceAdapterHolder toStreamingHttpService(BlockingHttpService service,
HttpExecutionStrategyInfluencer influencer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,31 @@
interface HttpClientBuilder<U, R, SDE extends ServiceDiscovererEvent<R>> {

/**
* Sets the {@link Executor} for all connections created from this builder.
* Sets the {@link Executor} for all clients created from this builder.
*
* @param executor {@link IoExecutor} to use.
* @return {@code this}.
*/
HttpClientBuilder<U, R, SDE> executor(Executor executor);

/**
* Sets the {@link IoExecutor} for all connections created from this builder.
* Sets the {@link IoExecutor} for all clients created from this builder.
*
* @param ioExecutor {@link IoExecutor} to use.
* @return {@code this}.
*/
HttpClientBuilder<U, R, SDE> ioExecutor(IoExecutor ioExecutor);

/**
* Sets the {@link BufferAllocator} for all connections created from this builder.
* Sets the {@link BufferAllocator} for all clients created from this builder.
*
* @param allocator {@link BufferAllocator} to use.
* @return {@code this}.
*/
HttpClientBuilder<U, R, SDE> bufferAllocator(BufferAllocator allocator);

/**
* Sets the {@link HttpExecutionStrategy} for all connections created from this builder.
* Sets the {@link HttpExecutionStrategy} for all clients created from this builder.
*
* @param strategy {@link HttpExecutionStrategy} to use.
* @return {@code this}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public final class HttpContextKeys {
public static final Key<HttpExecutionStrategy> HTTP_EXECUTION_STRATEGY_KEY =
newKey("HTTP_EXECUTION_STRATEGY_KEY", HttpExecutionStrategy.class);

/**
* Tracks the original API mode used for client API conversions
*/
public static final Key<HttpApiConversions.ClientAPI> HTTP_CLIENT_API_KEY =
bondolo marked this conversation as resolved.
Show resolved Hide resolved
newKey("HTTP_CLIENT_API_KEY", HttpApiConversions.ClientAPI.class);

private HttpContextKeys() {
// No instances
}
Expand Down
Loading