RedRose
RedRose

Reputation: 689

How to upload large files to Azure blob storage in background and responding 202 accepted right away?

I have a file upload webapi endpoint where it accept IFormFile . I want to upload large files that are any where 100Mbs to GBs to Azure blob storage. I want upload the file in background and return 202 accepted as soon as I see the length of the file is greater than some threshold.

I have the following controller and injected service code:

    [HttpPost]
    public async Task<IActionResult> UploadFilesAsync(IFormFile uploadedFile, CancellationToken cancellationToken = default)
    {
        // some other code . . . . 

        if (uploadedFile.Length > _appConfig.Value.Threshold)
             result = await _fileService.UploadFileAsync(uploadedFile, fileDataType, cancellationToken);
             
        //map result and more code . . .
        return CreatedAtRoute(nameof(GetFileAsync), new { fileId = result.FileId }, mappedDto);

    }
    
    public async Task<FileUploadResult> UploadFileAsync(IFormFile uploadedFile,CancellationToken cancellationToken)
    {
        var fileUploadResult = new fileUploadResult( . . .)
    
        _ = System.Threading.Tasks.Task.Run(async () =>
        {
            var processResult = await _blobStorage.SaveFileAsync(uploadedFile,cancellationToken);

            // upload is completed, update FileEntity status
            var processStatus = processResult.HasError ? ProcessStatus.Failed : ProcessStatus.Succeeded;
            await _fileRepository.UpdateFileEntityAsync(blobFileInfo, processStatus, cancellationToken);
        }, cancellationToken);

        return fileUploadResult ;
    }

I have tried Task.Run but I still notice that the api still hangs when uploading using postman and I also learned that Task.Run is not recommended. What can I use in .net6 to trigger upload process in background and respond with 202Accepted ?

Upvotes: 0

Views: 383

Answers (1)

Jason Pan
Jason Pan

Reputation: 21949

We can use background service, Coravel queueing services and signalr to implement it.

  1. Create a jobId in upload method, add pass it to background job method.

    var processResult = await _blobStorage.SaveFileAsync(uploadedFile,cancellationToken);
    // check the upload result
    
     // sample code, not test
     public Dictionary jobDic = new Dictionary<string_jobid, string_status>();
    
     private async Task PerformBackgroundJob(string jobId)
     {
         while(string_status=="uploading"){
             // TODO: report progress with SignalR
             await _hubContext.Clients.Group(jobId).SendAsync("progress", i);
             await Task.Delay(100);
         }
    
     }
    
  2. When the file uploaded, then we can get upload success message, then we can call frontend code or call RedirectToAction.

Related Link:

1. Communicate the status of a background job with SignalR

2. Repo

Upvotes: 1

Related Questions