Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for cancellation and request timeout #21

Closed
tomekit opened this issue Jan 4, 2025 · 4 comments
Closed

Support for cancellation and request timeout #21

tomekit opened this issue Jan 4, 2025 · 4 comments

Comments

@tomekit
Copy link

tomekit commented Jan 4, 2025

Thanks for this great package.

I've tried this package and it worked extremely well with the streamed response and huge file downloads. That's something not available for Dio just yet.

There are two bits that I find missing though.

a) Cancellation
Is it possible for this package to include: https://pub.dev/packages/cancellation_token_http instead of https://pub.dev/packages/http and provide the cancellation functionality?

Dio also supports cancellation: https://pub.dev/packages/dio#cancellation

b) Timeout
Is there any way to provide timeout?
https://pub.dev/packages/dio#dio-apis

Related links:
cfug/dio#1621
cfug/dio#1740

@Zekfad
Copy link
Owner

Zekfad commented Jan 4, 2025

Depending on your use case, you can try to use fetch_api directly, which has abort controller.

I don't think it's viable to switch http to other package as it's a breaking change and this package is intended specifically for http and tested using their compliance test suite.

I have plans to make dio adapter that facilities available fetch benefits, but I haven't found time for that yet.

If you can point relevant docs for implementing custom dio adapters I could work on it in a near future.

@Zekfad
Copy link
Owner

Zekfad commented Jan 4, 2025

Just remembered that you actually CAN cancel request in progress with cancel method:

final void Function() cancel;

If you're using fetch_client indirectly (meaning you receive static type of StreamedResponse) you can cast it to FetchResponse, as that's what fetch_client really returns.

If you need data timeout (when connection doesn't send any data for a specified period) you can use Stream.timeout.

If you need general timeout for request, you can either start a timer or use Stream.fold/reduce/join depending on your needs and then Future.timeout.

In both cases remember to call cancel after timeout to drop request.

@tomekit
Copy link
Author

tomekit commented Jan 4, 2025

Thanks for prompt response!

I have plans to make dio adapter that facilities available fetch benefits, but I haven't found time for that yet.
If you can point relevant docs for implementing custom dio adapters I could work on it in a near future.

That would be great.

Someone in the comment here: cfug/dio#1740 (comment) suggested to use:
https://pub.dev/packages/dio_compatibility_layer

However my experience falls short here, so I am not exactly sure about that one.

Description:

This package contains adapters for Dio which enables you to make use of other HTTP clients as the underlying implementation.

Currently, it supports compatibility with

[http](https://pub.dev/packages/http) 

==

Just remembered that you actually CAN cancel request in progress with cancel method:

That's great, I've reused existing code where cancelToken is exposed to the outside which can then cancel pending request. My approach is to check if cancelToken is cancelled and then call the cancel() on the response.

final response = await client.send(request);
 await for (final List<int> chunk in stream) {

      if (cancelToken.isCancelled) {
        response.cancel();
      }
 }

I haven't tested it just yet, but I expect this shall work.

If you need data timeout ...
If you need general timeout for request,...

Thanks, so far I need just "inactivity" timeout, so the timeout on the stream shall do the job:

stream.timeout(Duration(seconds: 10), onTimeout: (eventSink) {        
        response.cancel();
});

but it's good to know it's possible to also have general timeout.

Well, thanks for your great support so far.

I am going to play with this package little more, but so far so good.

@Zekfad
Copy link
Owner

Zekfad commented Jan 4, 2025

As of note, calling cancel wont produce an error (if you don't have content-lenght), stream would end same as if request completed. So you may want to communicate cancel to your UI from the place you call cancel.

Or because you use Stream.timeout you can add TimeoutException to evenSink and handle timeout from this transformed stream same as your other error handling.

I'll close this issue for now, as I think requested functions are already present.

@Zekfad Zekfad closed this as completed Jan 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants