Skip to content

Commit 445c47a

Browse files
authored
Merge pull request #2 from dart-lang/on-retry
Add an onRetry() callback
2 parents 694e34f + fc69df3 commit 445c47a

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

lib/http_retry.dart

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ class RetryClient extends BaseClient {
1717
final int _retries;
1818

1919
/// The callback that determines whether a request should be retried.
20-
final bool Function(StreamedResponse) _when;
20+
final bool Function(BaseResponse) _when;
2121

2222
/// The callback that determines how long to wait before retrying a request.
2323
final Duration Function(int) _delay;
2424

25+
/// The callback to call to indicate that a request is being retried.
26+
final void Function(BaseRequest, BaseResponse, int) _onRetry;
27+
2528
/// Creates a client wrapping [inner] that retries HTTP requests.
2629
///
2730
/// This retries a failing request [retries] times (3 by default). Note that
@@ -35,15 +38,20 @@ class RetryClient extends BaseClient {
3538
/// retry, then increases the delay by 1.5x for each subsequent retry. If
3639
/// [delay] is passed, it's used to determine the time to wait before the
3740
/// given (zero-based) retry.
41+
///
42+
/// If [onRetry] is passed, it's called immediately before each retry so that
43+
/// the client has a chance to perform side effects like logging.
3844
RetryClient(this._inner,
3945
{int retries,
40-
bool when(StreamedResponse response),
41-
Duration delay(int retryCount)})
46+
bool when(BaseResponse response),
47+
Duration delay(int retryCount),
48+
void onRetry(BaseRequest request, BaseResponse response, int retryCount)})
4249
: _retries = retries ?? 3,
4350
_when = when ?? ((response) => response.statusCode == 503),
4451
_delay = delay ??
4552
((retryCount) =>
46-
new Duration(milliseconds: 500) * math.pow(1.5, retryCount)) {
53+
new Duration(milliseconds: 500) * math.pow(1.5, retryCount)),
54+
_onRetry = onRetry {
4755
RangeError.checkNotNegative(_retries, "retries");
4856
}
4957

@@ -54,13 +62,18 @@ class RetryClient extends BaseClient {
5462
/// in order. It will wait for `delays[0]` after the initial request,
5563
/// `delays[1]` after the first retry, and so on.
5664
RetryClient.withDelays(Client inner, Iterable<Duration> delays,
57-
{bool when(StreamedResponse response)})
58-
: this._withDelays(inner, delays.toList(), when: when);
65+
{bool when(BaseResponse response),
66+
void onRetry(BaseRequest request, BaseResponse response, int retryCount)})
67+
: this._withDelays(inner, delays.toList(), when: when, onRetry: onRetry);
5968

6069
RetryClient._withDelays(Client inner, List<Duration> delays,
61-
{bool when(StreamedResponse response)})
70+
{bool when(BaseResponse response),
71+
void onRetry(BaseRequest request, BaseResponse response, int retryCount)})
6272
: this(inner,
63-
retries: delays.length, delay: (retryCount) => delays[retryCount]);
73+
retries: delays.length,
74+
delay: (retryCount) => delays[retryCount],
75+
when: when,
76+
onRetry: onRetry);
6477

6578
Future<StreamedResponse> send(BaseRequest request) async {
6679
var splitter = new StreamSplitter(request.finalize());
@@ -74,6 +87,7 @@ class RetryClient extends BaseClient {
7487
// dangling connections.
7588
response.stream.listen((_) {}).cancel()?.catchError((_) {});
7689
await new Future.delayed(_delay(i));
90+
if (_onRetry != null) _onRetry(request, response, i);
7791
i++;
7892
}
7993
}

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: http_retry
2-
version: 0.1.0-dev
2+
version: 0.1.0
33
description: HTTP client middleware that automatically retries requests.
44
author: Dart Team <[email protected]>
55
homepage: https://github.com/dart-lang/http_retry

test/http_retry_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,23 @@ void main() {
162162
});
163163
});
164164

165+
test("calls onRetry for each retry", () async {
166+
var count = 0;
167+
var client = new RetryClient(
168+
new MockClient(
169+
expectAsync1((_) async => new Response("", 503), count: 3)),
170+
retries: 2,
171+
delay: (_) => Duration.ZERO,
172+
onRetry: expectAsync3((request, response, retryCount) {
173+
expect(request.url, equals(Uri.parse("http://example.org")));
174+
expect(response.statusCode, equals(503));
175+
expect(retryCount, equals(count));
176+
count++;
177+
}, count: 2));
178+
var response = await client.get("http://example.org");
179+
expect(response.statusCode, equals(503));
180+
});
181+
165182
test("copies all request attributes for each attempt", () async {
166183
var client = new RetryClient.withDelays(
167184
new MockClient(expectAsync1((request) async {

0 commit comments

Comments
 (0)