File tree Expand file tree Collapse file tree 2 files changed +66
-1
lines changed
pkg/_pub_shared/lib/utils Expand file tree Collapse file tree 2 files changed +66
-1
lines changed Original file line number Diff line number Diff line change @@ -32,7 +32,7 @@ SearchClient get searchClient => ss.lookup(#_searchClient) as SearchClient;
3232/// indexed data.
3333class SearchClient {
3434 /// The HTTP client used for making calls to our search service.
35- final _httpClient = httpRetryClient ();
35+ final _httpClient = httpRenewableClient ();
3636
3737 /// Before this timestamp we may use the fallback search service URL, which
3838 /// is the unversioned service URL, potentially getting responses from an
Original file line number Diff line number Diff line change @@ -83,6 +83,11 @@ Future<K> httpGetWithRetry<K>(
8383 },
8484 maxAttempts: maxAttempts,
8585 retryIf: (e) => _retryIf (e) || (retryIf != null && retryIf (e)),
86+ onRetry: (_) {
87+ if (client is _RenewableClient ) {
88+ client.renew ();
89+ }
90+ },
8691 );
8792}
8893
@@ -113,3 +118,63 @@ class UnexpectedStatusException implements Exception {
113118 @override
114119 String toString () => 'UnexpectedStatusException: $message ' ;
115120}
121+
122+ /// Creates a client that will be renewed when a HTTP retry happens.
123+ http.Client httpRenewableClient () => _RenewableClient ();
124+
125+ class _RenewableClient extends http.BaseClient {
126+ var _client = _Client (http.Client ());
127+
128+ @override
129+ Future <http.StreamedResponse > send (http.BaseRequest request) async {
130+ return await _client.send (request);
131+ }
132+
133+ void renew () {
134+ final c = _client;
135+ _client = _Client (http.Client ());
136+ c.close ();
137+ }
138+
139+ @override
140+ void close () {
141+ _client.close ();
142+ }
143+ }
144+
145+ class _Client extends http.BaseClient {
146+ final http.Client _client;
147+ final _pending = < Future > [];
148+ var _closing = false ;
149+
150+ _Client (this ._client);
151+
152+ @override
153+ Future <http.StreamedResponse > send (http.BaseRequest request) async {
154+ if (_closing) {
155+ throw StateError ('HTTP client is closed.' );
156+ }
157+ final f = _client.send (request);
158+ _pending.add (f);
159+ try {
160+ return await f;
161+ } finally {
162+ _pending.remove (f);
163+ if (_closing && _pending.isEmpty) {
164+ _client.close ();
165+ }
166+ }
167+ }
168+
169+ @override
170+ void close () {
171+ _closing = true ;
172+ if (_pending.isEmpty) {
173+ _client.close ();
174+ return ;
175+ }
176+ unawaited (Future .delayed (Duration (minutes: 1 ), () {
177+ _client.close ();
178+ }));
179+ }
180+ }
You can’t perform that action at this time.
0 commit comments