Skip to content

HTTP Retry Support - #255

Merged
hiranya911 merged 21 commits into
masterfrom
hkj-http-retry
Mar 14, 2019
Merged

HTTP Retry Support#255
hiranya911 merged 21 commits into
masterfrom
hkj-http-retry

Conversation

@hiranya911

@hiranya911 hiranya911 commented Feb 25, 2019

Copy link
Copy Markdown
Contributor

We are in the process of implementing HTTP retry support across all Admin SDKs. Specifically, we want to retry an HTTP request in the following situations:

  • All I/O errors (i.e. network errors, socket errors etc)
  • HTTP 500 and 503 errors

This PR lays the foundation for supporting HTTP retries in the Java Admin SDK. However, we are not enabling retries for any of the APIs just yet. This will need some more refactoring in each of the modules, and therefore we will do it later in an incremental fashion.

@schmidt-sebastian schmidt-sebastian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some high quality code! :) The comments I left are mainly there to push you to re-use more GAX classes. Can you see if we can use their settings objects? That might be more elegant that spinning our own objects as intermediaries.

I haven't yet looked at the tests.

Comment thread src/main/java/com/google/firebase/internal/FirebaseRequestInitializer.java Outdated
Comment thread src/main/java/com/google/firebase/internal/RetryConfig.java
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.api.client.util.BackOff;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/main/java/com/google/firebase/internal/RetryConfig.java
/**
* Sets a list of HTTP status codes that should be retried. If null or empty, HTTP requests
* will not be retried as long as they result in some HTTP response message. I/O errors
* will still be retried.

@schmidt-sebastian schmidt-sebastian Feb 26, 2019

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have had some long discussion with the Firestore backend team about retrying requests that were dropped and never responded to. Unless we know for certain that no byte made it across the wire, it was decided that we cannot retry. Since you are essentially building a retry framework for a wide variety of consumers, I would advise that we don't retry I/O errors by default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Python and Go we have enabled this, but I can see why this can be a bad idea in some cases. Added an option to make this configurable via RetryConfig.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update comment to state that this is only true if setRetryOnIOExceptions is enabled.

Comment thread src/main/java/com/google/firebase/internal/RetryConfig.java
Comment thread src/main/java/com/google/firebase/internal/RetryInitializer.java
@hiranya911

Copy link
Copy Markdown
Contributor Author

Thanks @schmidt-sebastian. I've made some changes and responded to your comments. In general, I don't see how to reuse gax retry mechanism in our code, since we don't use gax. But I've managed to make most of the other improvements suggested.

@schmidt-sebastian schmidt-sebastian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for getting back to me on my comments. While I do think we could go out of our way here and use existing retry logic, I can certainly understand your reasoning. Otherwise, this PR looks great. I have also since looked at the tests and am signing off on those as well. I left some nits, but nothing major.

Comment thread src/main/java/com/google/firebase/internal/RetryInitializer.java Outdated
Comment thread src/test/java/com/google/firebase/internal/RetryConfigTest.java
/**
* Sets a list of HTTP status codes that should be retried. If null or empty, HTTP requests
* will not be retried as long as they result in some HTTP response message. I/O errors
* will still be retried.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update comment to state that this is only true if setRetryOnIOExceptions is enabled.

Comment thread src/test/java/com/google/firebase/internal/RetryInitializerTest.java Outdated

assertEquals(10, sleeper.getCount());
assertArrayEquals(
new long[]{500, 1000, 2000, 4000, 8000, 16000, 32000, 64000, 120000, 120000},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are quite a few tests in this PR that test the same feature at different levels (see testExponentialBackOff). You can certainly leave this as is, but it might be worth considering to reduce duplication in future PRs.

Comment thread src/main/java/com/google/firebase/internal/RetryConfig.java
* Copied DateUtils source from Apache HC

* Updated reference link

* Used locks instead of thread locals; Added tests

* Added a NOTICE file for third-party code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants