-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
expose HttpRequest.setInterceptor to allow for throttled uploads #3534
Comments
This would require work in google-http-java-client. cc/ @chingor13 |
Is there a reason this needs to be modifiable after construction? It looks like you can accomplish wrapping an additional HttpRequestInitializer by extending the class MyTransportOptions extends HttpTransportOptions {
// TODO: make your own constructor or builder
@Override
public HttpRequestInitializer getHttpRequestInitializer(final ServiceOptions<?, ?> serviceOptions) {
return new InterceptingHttpRequestInitializer(super.getHttpRequestInitiallizer(serviceOptions));
}
}
StorageOptions options = StorageOptions
.newBuilder()
.setTransportOptions(new MyTransportOptions())
.build();
Storage storage = options.getService(); |
@chingor13 That works for our use-case, thanks. I must have missed that I can't think of another use-case which would require modifying |
closing this issue as its resolved. |
@chingor13 We're only now revisiting this issue... what you suggested is not feasible (statically) because @ajaaym could you please reopen the issue unless there is a less hacky workaround as I'd originally suggested? |
@srosenberg , @sduskis what is new feature might be needed from the api: storage now by this feature request? |
@ajaaym Recently, we had to also throttle downloads to minimize GC disturbances during (data) reload. I was unable to find a clean way to do this via existing API. Instead, the following workaround was implemented which suffers from using reflection (see second snippet) and extending protected Storage installHttpThrottler(StorageOptions.Builder storageOptions) {
return storageOptions
.setTransportOptions(HttpTransportOptions.newBuilder().setHttpTransportFactory(new ThrottledHttpTransportFactory()).build())
.build()
.getService();
} class ThrottledHttpTransportFactory implements HttpTransportFactory {
public HttpTransport create() {
NetHttpTransport result = new NetHttpTransport();
try {
//TODO(SR): resorting to reflection hack since there is no other way to update connectionFactory
//see https://github.com/GoogleCloudPlatform/google-cloud-java/issues/3534
FieldUtils.writeDeclaredField(result, "connectionFactory", new ThrottledConnectionFactory(), true);
} catch (Exception ex) {
throw new RuntimeException("Unable to install ThrottledConnectionFactory", ex);
}
return result;
}
} class ThrottledConnectionFactory extends DefaultConnectionFactory {
@Override
public HttpURLConnection openConnection(URL url) throws IOException {
return new ThrottledUrlConnection(super.openConnection(url), url);
}
} |
@srosenberg Do you want to intercept inputstream or connection factory? For inputstream, do you mean by getting raw inputstream? You can create transport factory like below without using reflection.
|
@ajaaym Thanks, somehow I missed the (availability of) factory; that solves the reflection hack. The other remaining issue is having to extend class ThrottledUrlConnection extends HttpURLConnection {
HttpURLConnection delegate;
ThrottledUrlConnection(HttpURLConnection delegate, URL url) {
super(url);
this.delegate = delegate;
}
@Override
public InputStream getInputStream() throws IOException {
return new ThrottledInputStream(delegate.getInputStream(), rateLimiter, throughputMeter);
}
// followed by a long list of overridden methods to redirect via 'delegate'
....
} |
@srosenberg as of now you can use response interceptor, but you have to use reflection to set the content after calling getContent(). You can create new feature request in that repo to allow overriding content in HttpResponse. |
@ajaaym I am happy to create a new feature request for response interceptor in |
Issue created: googleapis/google-http-java-client#586 |
We have a multi-threaded uploader which transfers large files from local disk to GCS. The uploader is co-located with our low-latency app. inside the JVM. To control latency, we must throttle the uploader. Our best workaround involves resorting to reflection in order to install
HttpRequest
interceptor which effectively wrapsHttpContent
with a throttledOutputStream
; e.g.,The text was updated successfully, but these errors were encountered: