d-markey / squadron

Multithreading and worker thread pool for Dart / Flutter, to offload CPU-bound and heavy I/O tasks to Isolate or Web Worker threads.
https://pub.dev/packages/squadron
MIT License
79 stars 0 forks source link

Is it possible to make http-request with Squadron? #31

Closed abigotado closed 9 months ago

abigotado commented 9 months ago

Hi!

I have studied the documentation and example, but I'm still not certain how can I create an http-request with Squadron? If it's possible.

I have a post-request, which is uploading some file. And I want to perform it in an isolated worker (on web). And also I need to listen to the upload progress somehow.

Is that possible? And how can I do that?

d-markey commented 9 months ago

You can use package http in your service and make HTTP calls from there, no problem. I believe that's what @sabin26 is doing (https://github.com/d-markey/squadron/issues/29). In your main app, you'd use a file picker to let users select a file, and I believe you'd have to read the byte content in your main app and pass the plain bytes to your service. The reason is Web workers will not allow any data structures to be passed around, they have to be transferable.

To monitor progress, I guess the service method would return a stream with progress events so you can update your UI. However I don't know if any package currently supports that because it means you want to listen to events raised by JavaScript's XmlHttpRequest. http doesn't expose these events and does not provide any progress information (per https://github.com/dart-lang/http/blob/master/pkgs/http/lib/src/browser_client.dart). There's an issue for this (https://github.com/dart-lang/http/issues/752) but answers target native plaforms, not Web.

sabin26 commented 9 months ago

Hi @abigotado, You can send http request with squadron.

Code Sample

@SquadronService(baseUrl: '/services')
class HttpService {
  HttpService();

  @SquadronMethod()
  Future<Response?> sendRequest({
    final String method = 'post',
    final String url,
    final Map<String, String>? headers,
    required final String filePath, // path of the file to upload
    required final CancellationToken? cancelToken,
  }) async {
    // send http request like how you would normally do
    return null;
  }
}

Few notes to remember

  1. You can use package: dio to send file and listen to its upload progress.
  2. You can convert the above method to a Stream to provide the upload progress to the main thread.
  3. The return type (Response) must be transferrable between web workers. Basic primitives such as: String, int, etc. are supported but complex data structures must be marshalled or have fromJson/toJson methods. In your case, you can just stream the progress as integer or double.
abigotado commented 9 months ago

@sabin26 Thank you very much! It works perfectly!

And thank you, guys for quick answers and cool package!