-
Notifications
You must be signed in to change notification settings - Fork 16
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
Add support for call timeouts #70
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,13 +29,13 @@ | |
import com.palantir.dialogue.HttpMethod; | ||
import com.palantir.dialogue.PathTemplate; | ||
import com.palantir.dialogue.Request; | ||
import com.palantir.dialogue.Response; | ||
import com.palantir.dialogue.Serializer; | ||
import com.palantir.dialogue.TypeMarker; | ||
import com.palantir.dialogue.UrlBuilder; | ||
import com.palantir.logsafe.Preconditions; | ||
import java.io.IOException; | ||
import java.time.Duration; | ||
import java.util.Map; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
// Example of the implementation code conjure would generate for a simple SampleService. | ||
public final class SampleServiceClient { | ||
|
@@ -77,7 +77,7 @@ public HttpMethod httpMethod() { | |
}; | ||
|
||
/** Returns a new blocking {@link SampleService} implementation whose calls are executed on the given channel. */ | ||
public static SampleService blocking(Channel channel, ConjureRuntime runtime) { | ||
public static SampleService blocking(Channel channel, ConjureRuntime runtime, Duration readTimeout) { | ||
return new SampleService() { | ||
|
||
private Serializer<String> stringToStringSerializer = | ||
|
@@ -98,10 +98,12 @@ public String stringToString(String objectId, String header, String body) { | |
.build(); | ||
|
||
Call call = channel.createCall(STRING_TO_STRING, request); | ||
ListenableFuture<Response> response = Calls.toFuture(call); | ||
ListenableFuture<String> response = Futures.transform( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thoughts on composing the timeouts as a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm. it wouldn't be so straightforward, because then the async and the blocking client would need different types of channels. (the async client as it stands doesn't do timeouts as callers are in control.) I think I'd revisit that problem when exposing clients that interact with an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (sorry, missed this comment before the last one I posted) It seems like async clients should still enforce timeouts on the requests/time-to-response, in which case it'd be the same Channel impl? |
||
Calls.toFuture(call), | ||
r -> stringToStringDeserializer.deserialize(r), | ||
MoreExecutors.directExecutor()); | ||
try { | ||
// TODO(rfink): Figure out how to inject read/write timeouts | ||
return stringToStringDeserializer.deserialize(response.get()); | ||
return response.get(readTimeout.toMillis(), TimeUnit.MILLISECONDS); | ||
} catch (Throwable t) { | ||
throw Exceptions.unwrapExecutionException(t); | ||
} | ||
|
@@ -112,9 +114,12 @@ public void voidToVoid() { | |
Request request = Request.builder().build(); | ||
|
||
Call call = channel.createCall(VOID_TO_VOID, request); | ||
ListenableFuture<Response> response = Calls.toFuture(call); | ||
ListenableFuture<Void> deserializedResponse = Futures.transform( | ||
Calls.toFuture(call), | ||
r -> voidToVoidDeserializer.deserialize(r), | ||
MoreExecutors.directExecutor()); | ||
try { | ||
voidToVoidDeserializer.deserialize(response.get()); | ||
deserializedResponse.get(readTimeout.toMillis(), TimeUnit.MILLISECONDS); | ||
} catch (Throwable t) { | ||
throw Exceptions.unwrapExecutionException(t); | ||
} | ||
|
@@ -149,14 +154,7 @@ public ListenableFuture<String> stringToString(String objectId, String header, S | |
Call call = channel.createCall(STRING_TO_STRING, request); | ||
return Futures.transform( | ||
Calls.toFuture(call), | ||
response -> { | ||
try { | ||
// TODO(rfink): The try/catch is a bit odd here. | ||
return stringToStringDeserializer.deserialize(response); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Failed to deserialize response", e); | ||
} | ||
}, | ||
response -> stringToStringDeserializer.deserialize(response), | ||
MoreExecutors.directExecutor()); | ||
} | ||
|
||
|
@@ -167,14 +165,7 @@ public ListenableFuture<Void> voidToVoid() { | |
Call call = channel.createCall(VOID_TO_VOID, request); | ||
return Futures.transform( | ||
Calls.toFuture(call), | ||
response -> { | ||
try { | ||
voidToVoidDeserializer.deserialize(response); | ||
return null; | ||
} catch (IOException e) { | ||
throw new RuntimeException("Failed to deserialize response", e); | ||
} | ||
}, | ||
response -> voidToVoidDeserializer.deserialize(response), | ||
MoreExecutors.directExecutor()); | ||
} | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering if it'd make more sense for this to be a builder-pattern thing or possibly for the third arg to be some kind of settings object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a TODO, think that'd be a separate PR.