Reputation: 2075
Azure blob service allows us to pass a cancel filter which can be used to cancel an upload (Example: How to cancel an upload started with BlobService.createBlockBlobFromBrowserFile?). It works fine for an individual upload, but it doesn't work well for situations when client is trying to upload multiple files. The problem is that cancel filter is an attribute of service itself, not an individual upload, so cancelling one upload cancels all the uploads. Is there any way (via typescript/JavaScript client) to cancel one upload while letting others go undisturbed?
Upvotes: 4
Views: 2093
Reputation: 23121
The package azure-storage
is legacy. Now Microsoft suggest customers use the new sdk V12 @azure/storage-blob
. if you use the new SDK, we can use AbortController
to cancel one operation. For more details, please refer to here.
For example (I test it in angular application)
npm install @azure/storage-blob @azure/abort-controller
(window as any).global = window;
(window as any).process = require( 'process' );
(window as any).Buffer = require( 'buffer' ).Buffer;
<label class="btn btn-default">
<input type="file"
id="file"
multiple
(change)="onFileChange($event)">
</label>
<div *ngFor="let item of fileInfos" class="mb-2">
<span>{{ item.file.name }}</span>
<div class="progress">
<div
class="progress-bar progress-bar-info progress-bar-striped"
role="progressbar"
attr.aria-valuenow=" {{ item.value }}"
aria-valuemin="0"
aria-valuemax="100"
[ngStyle]="{ width: item.value + '%' }"
>
{{ item.value }}%
</div>
</div>
<button class="btn btn-primary" (click)='item.upload()'>upload</button>
<button class="btn btn-primary" (click)='item.cancel()'>cancel</button>
</div>
FileInfo
calssimport {AbortController} from '@azure/abort-controller'
import {BlobServiceClient,AnonymousCredential} from '@azure/storage-blob'
export class FileInfo{
file : File
value=0
private controller = new AbortController()
constructor(message: File) {
this.file = message;
}
async upload(){
try {
const blobServiceClient= new BlobServiceClient('https://<accountNmae>.blob.core.windows.net/?<sas token>',
new AnonymousCredential)
const containerClient= blobServiceClient.getContainerClient('<>')
const blob= containerClient.getBlockBlobClient(this.file.name)
console.log(`start uploading file ${this.file.name}`)
const total =this.file.size
await blob.uploadData(this.file,{
abortSignal: this.controller.signal,
blobHTTPHeaders:{blobContentType: this.file.type},
blockSize: 4*1024*1024,
onProgress : (ev) =>{
console.log(`You have uploaded ${ev.loadedBytes} bytes`);
this.value=Math.round(100 * ev.loadedBytes/ total);
}
})
console.log(` upload file ${this.file.name} successfully`)
} catch (error) {
console.log(`cannot upload file ${this.file.name}, it return error ${error}`)
}
}
cancel(){
this.controller.abort()
console.log(`cancel uploading file ${this.file.name}`)
}
}
...
fileInfos: Array<FileInfo> =[]
onFileChange(event:any) {
this.fileInfos=[]
for (var i = 0; i < event.target.files.length; i++) {
var file =event.target.files[i]
this.fileInfos.push( new FileInfo(file))
}
}
Upvotes: 6
Reputation: 2075
I was able to make it work by creating multiple cancel filters and cancel just a specific cancel filter associated with the that file upload.
Upvotes: -1