Reactive Programming Case Study 2 - Multiple files upload

Reactive Programming Case Study 2 - Multiple files upload

·

1 min read

Requirements:

  • User may select multiple files using <input type="file" multiple>
  • Once files are selected, we want multiple http requests sent (one request per file) to upload the files to a web server, with a concurrency level n, meaning n files can be uploaded simultaneously.
  • If one request fails, automatically retry it up to 3 times with a back off rate at 1.5
  • Show progress bar/message somehow.

multiple_file_uploads.PNG

The js code for uploading the selected files:

/**
  *  For callers interested in only file uploading completed events, should provide 'completed' callback instead of 'next' callback.
  */
export function uploadFiles(
  files: File[],
  http: HttpClient,
  urlFn: (file: File) => string,
  progressUpdator: (progress: number) => void,
  concurrency = 3
) {

  return from(files).pipe(
    mergeMap(x => {
      const targetUrl = urlFn(x);
      return http.put(targetUrl, x, {
        reportProgress: true,
        observe: 'events',
      }).pipe(
        retryWhen(errors => errors.pipe(
          take(3),
          switchMap((err, idx) => {
            // retry with backoff rate 2
            return timer(500 * Math.pow(2, idx))
          }))
        ),
        tap(evt => {
          // notify that upload progress has changed
          if (evt.type === HttpEventType.UploadProgress) {
            progressUpdator(evt.loaded / (evt.total/100.0))
          }
        })        
      )
    }, concurrency)
  );
}

More interestingly, rxjs's .NET implementation rxNet, can be used similarly in .NET MAUI, Xamarin and even the dinosaur Windows Forms. Please stay tuned and I will publish a new article for that.