Implement retry for transient errors in WHOIS server

We now attempt to retry Whois queries in the event of a short-lived error. Currently, we consider 'DatastoreTimeoutException' and 'DatastoreFailureException' as transient.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=152044934
This commit is contained in:
larryruili 2017-04-03 12:49:40 -07:00 committed by Ben McIlwain
parent c3df4e26a3
commit 7359cc13b8
6 changed files with 77 additions and 13 deletions

View file

@ -36,6 +36,8 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.appengine.api.datastore.DatastoreFailureException;
import com.google.appengine.api.datastore.DatastoreTimeoutException;
import google.registry.model.domain.DomainResource;
import google.registry.model.ofy.Ofy;
import google.registry.model.registrar.Registrar;
@ -43,7 +45,9 @@ import google.registry.model.registry.Registry;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.FakeSleeper;
import google.registry.testing.InjectRule;
import google.registry.util.Retrier;
import google.registry.whois.WhoisMetrics.WhoisMetric;
import java.io.IOException;
import java.io.Reader;
@ -75,6 +79,7 @@ public class WhoisServerTest {
whoisServer.whoisMetrics = new WhoisMetrics();
whoisServer.metricBuilder = WhoisMetric.builderForRequest(clock);
whoisServer.disclaimer = "Doodle Disclaimer";
whoisServer.retrier = new Retrier(new FakeSleeper(clock), 3);
return whoisServer;
}
@ -490,4 +495,24 @@ public class WhoisServerTest {
verify(server.whoisMetrics).recordWhoisMetric(eq(expected));
assertThat(response.getPayload()).isEqualTo("Internal Server Error");
}
@Test
public void testRun_retryOnTransientFailure() throws Exception {
persistResource(makeHostResource("ns1.cat.lol", "1.2.3.4"));
WhoisServer server = newWhoisServer("ns1.cat.lol");
WhoisResponse expectedResponse =
server.whoisReader.readCommand(server.input, clock.nowUtc()).executeQuery(clock.nowUtc());
WhoisReader mockReader = mock(WhoisReader.class);
WhoisCommand mockCommand = mock(WhoisCommand.class);
when(mockReader.readCommand(any(Reader.class), any(DateTime.class))).thenReturn(mockCommand);
when(mockCommand.executeQuery(any(DateTime.class)))
.thenThrow(new DatastoreFailureException("Expected transient exception #1"))
.thenThrow(new DatastoreTimeoutException("Expected transient exception #2"))
.thenReturn(expectedResponse);
server.whoisReader = mockReader;
server.run();
assertThat(response.getPayload()).isEqualTo(loadWhoisTestFile("whois_server_nameserver.txt"));
}
}

View file

@ -18,6 +18,7 @@ import dagger.Component;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.request.RequestModule;
import google.registry.util.SystemClock.SystemClockModule;
import google.registry.util.SystemSleeper.SystemSleeperModule;
import javax.inject.Singleton;
@Singleton
@ -25,6 +26,7 @@ import javax.inject.Singleton;
ConfigModule.class,
RequestModule.class,
SystemClockModule.class,
SystemSleeperModule.class,
WhoisModule.class,
})
interface WhoisTestComponent {