Skip to content

Commit

Permalink
♻️ Refactor using WeakReference
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexV525 committed Jun 20, 2024
1 parent 8fad21c commit 77d9f4d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 68 deletions.
45 changes: 10 additions & 35 deletions dio/lib/src/adapters/io_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ class IOHttpClientAdapter implements HttpClientAdapter {
HttpClient? _cachedHttpClient;
bool _closed = false;

final cancelFutureOperationPool =
<Future<void>, Set<CancelableOperation<ResponseBody>>>{};
final cancelFutureRequestPool = <Future<void>, Set<HttpClientRequest>>{};

@override
Future<ResponseBody> fetch(
RequestOptions options,
Expand All @@ -77,24 +73,11 @@ class IOHttpClientAdapter implements HttpClientAdapter {
final operation = CancelableOperation.fromFuture(
_fetch(options, requestStream, cancelFuture),
);

if (cancelFuture != null) {
cancelFutureOperationPool.putIfAbsent(cancelFuture, () => {});
cancelFutureRequestPool.putIfAbsent(cancelFuture, () => {});

cancelFuture.whenComplete(() {
cancelFutureOperationPool[cancelFuture]?.forEach((e) => e.cancel());
cancelFutureOperationPool.remove(cancelFuture);
cancelFutureRequestPool[cancelFuture]?.forEach((e) => e.abort());
cancelFutureRequestPool.remove(cancelFuture);
});

cancelFutureOperationPool[cancelFuture]!.add(operation);
}

return operation.value.whenComplete(
() => cancelFutureOperationPool[cancelFuture]?.remove(operation),
);
final wr = WeakReference<CancelableOperation<ResponseBody>>(operation);
cancelFuture?.whenComplete(() {
wr.target?.cancel();
});
return operation.value;
}

Future<ResponseBody> _fetch(
Expand All @@ -121,9 +104,10 @@ class IOHttpClientAdapter implements HttpClientAdapter {
request = await reqFuture;
}

if (cancelFuture != null) {
cancelFutureRequestPool[cancelFuture]!.add(request);
}
final wr = WeakReference<HttpClientRequest>(request);
cancelFuture?.whenComplete(() {
wr.target?.abort();
});

// Set Headers
options.headers.forEach((key, value) {
Expand Down Expand Up @@ -164,13 +148,6 @@ class IOHttpClientAdapter implements HttpClientAdapter {
request.maxRedirects = options.maxRedirects;
request.persistentConnection = options.persistentConnection;

void removeRequestInPool() {
if (cancelFuture == null) {
return;
}
cancelFutureRequestPool[cancelFuture]?.remove(request);
}

if (requestStream != null) {
// Transform the request data.
Future<dynamic> future = request.addStream(requestStream);
Expand All @@ -180,7 +157,6 @@ class IOHttpClientAdapter implements HttpClientAdapter {
sendTimeout,
onTimeout: () {
request.abort();
removeRequestInPool();
throw DioException.sendTimeout(
timeout: sendTimeout,
requestOptions: options,
Expand All @@ -198,15 +174,14 @@ class IOHttpClientAdapter implements HttpClientAdapter {
receiveTimeout,
onTimeout: () {
request.abort();
removeRequestInPool();
throw DioException.receiveTimeout(
timeout: receiveTimeout,
requestOptions: options,
);
},
);
}
final responseStream = await future.whenComplete(removeRequestInPool);
final responseStream = await future;

if (validateCertificate != null) {
final host = options.uri.host;
Expand Down
43 changes: 10 additions & 33 deletions plugins/http2_adapter/lib/src/http2_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ class Http2Adapter implements HttpClientAdapter {
/// Handles [DioH2NotSupportedException] and returns a [ResponseBody].
H2NotSupportedCallback? onNotSupported;

final cancelFutureOperationPool =
<Future<void>, Set<CancelableOperation<ResponseBody>>>{};
final cancelFutureRequestPool = <Future<void>, Set<ClientTransportStream>>{};

@override
Future<ResponseBody> fetch(
RequestOptions options,
Expand All @@ -56,25 +52,11 @@ class Http2Adapter implements HttpClientAdapter {
final operation = CancelableOperation.fromFuture(
_fetch(options, requestStream, cancelFuture, redirects),
);

if (cancelFuture != null) {
cancelFutureOperationPool.putIfAbsent(cancelFuture, () => {});
cancelFutureRequestPool.putIfAbsent(cancelFuture, () => {});

cancelFuture.whenComplete(() {
cancelFutureOperationPool[cancelFuture]?.forEach((e) => e.cancel());
cancelFutureOperationPool.remove(cancelFuture);
cancelFutureRequestPool[cancelFuture]
?.forEach((e) => e.outgoingMessages.close());
cancelFutureRequestPool.remove(cancelFuture);
});

cancelFutureOperationPool[cancelFuture]!.add(operation);
}

return operation.value.whenComplete(
() => cancelFutureOperationPool[cancelFuture]?.remove(operation),
);
final wr = WeakReference<CancelableOperation<ResponseBody>>(operation);
cancelFuture?.whenComplete(() {
wr.target?.cancel();
});
return operation.value;
}

Future<ResponseBody> _fetch(
Expand Down Expand Up @@ -150,17 +132,13 @@ class Http2Adapter implements HttpClientAdapter {

// Creates a new outgoing stream.
final stream = transport.makeRequest(headers);
final streamWR = WeakReference<ClientTransportStream>(stream);

final hasRequestData = requestStream != null;
if (hasRequestData && cancelFuture != null) {
cancelFutureRequestPool[cancelFuture]!.add(stream);
}

void removeRequestInPool() {
if (cancelFuture == null) {
return;
}
cancelFutureRequestPool[cancelFuture]?.remove(stream);
cancelFuture.whenComplete(() {
streamWR.target?.outgoingMessages.close();
});
}

List<Uint8List>? list;
Expand All @@ -179,7 +157,6 @@ class Http2Adapter implements HttpClientAdapter {
sendTimeout,
onTimeout: () {
stream.outgoingMessages.close().catchError((_) {});
removeRequestInPool();
throw DioException.sendTimeout(
timeout: sendTimeout,
requestOptions: options,
Expand All @@ -189,7 +166,7 @@ class Http2Adapter implements HttpClientAdapter {
}
await requestStreamFuture;
}
await stream.outgoingMessages.close().whenComplete(removeRequestInPool);
await stream.outgoingMessages.close();

final responseSink = StreamController<Uint8List>();
final responseHeaders = Headers();
Expand Down

0 comments on commit 77d9f4d

Please sign in to comment.