Skip to content

Commit fc69df3

Browse files
committed
Add an onRetry() callback
1 parent 7ad83ad commit fc69df3

File tree

3 files changed

+36
-7
lines changed

3 files changed

+36
-7
lines changed

lib/http_retry.dart

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ class RetryClient extends BaseClient {
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,
4046
bool when(BaseResponse response),
41-
Duration delay(int retryCount)})
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,15 +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(BaseResponse 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(BaseResponse response)})
70+
{bool when(BaseResponse response),
71+
void onRetry(BaseRequest request, BaseResponse response, int retryCount)})
6272
: this(inner,
6373
retries: delays.length,
6474
delay: (retryCount) => delays[retryCount],
65-
when: when);
75+
when: when,
76+
onRetry: onRetry);
6677

6778
Future<StreamedResponse> send(BaseRequest request) async {
6879
var splitter = new StreamSplitter(request.finalize());
@@ -76,6 +87,7 @@ class RetryClient extends BaseClient {
7687
// dangling connections.
7788
response.stream.listen((_) {}).cancel()?.catchError((_) {});
7889
await new Future.delayed(_delay(i));
90+
if (_onRetry != null) _onRetry(request, response, i);
7991
i++;
8092
}
8193
}

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)