How to cancel an upload started with BlobService.createBlockBlobFromBrowserFile?

心不动则不痛 提交于 2021-02-09 10:56:12

问题


I'm using Microsoft Azure Storage Client Library's BlobService.createBlockBlobFromBrowserFile to allow users to upload files to an Azure Storage container. I'd like to provide a way for them to cancel an in-progress upload, e.g. in case it's big and taking too long or they chose the wrong file. Is there any way I can do this though? I can't see anything obvious in the API.

My code is based on these samples, e.g.

var file = document.getElementById('fileinput').files[0];

var customBlockSize = file.size > 1024 * 1024 * 32 ? 1024 * 1024 * 4 : 1024 * 512;
blobService.singleBlobPutThresholdInBytes = customBlockSize;

var finishedOrError = false;
var speedSummary = blobService.createBlockBlobFromBrowserFile('mycontainer', file.name, file, {blockSize : customBlockSize}, function(error, result, response) {
    finishedOrError = true;
    if (error) {
        // Upload blob failed
    } else {
        // Upload successfully
    }
});
refreshProgress();

The SpeedSummary object returned from createBlockBlobFromBrowserFile is I think this one, which doesn't have anything like that available.

Also asked on MSDN here.


回答1:


MSDN directed me to this github issue discussing the same question, and using a custom filter as a solution.

So here's my first attempt at a filter that lets you cancel an in-progress upload. This is certainly not perfect, but appears to work in my rudimentary testing. I'd love to get feedback from people actually familiar with this. Is this the right way to cancel, i.e. just return from within the callback?

I haven't tested it with any other filters applied, e.g. a retry filter. Also it assumes you only ever have one upload: it doesn't reset its state or expect multiple uploads.

// Filter allowing us to cancel an in-progress upload by setting 'cancel' to true.
// This doesn't cancel file chunks currently being uploaded, so the upload does continue 
// for a while after this is triggered. If the last chunks have already been sent the 
// upload might actually complete (??)
// See http://azure.github.io/azure-storage-node/StorageServiceClient.html#withFilter
var cancelUploadFilter = {
    cancel: false,              // Set to true to cancel an in-progress upload

    loggingOn: true,            // Set to true to see info on console

    onCancelComplete: null,     // Set to a function you want called when a cancelled request is (probably?) complete, 
                                // i.e. when returnCounter==nextCounter. Because when you cancel an upload it can be many 
                                // seconds before the in-progress chunks complete. 

    // Internal from here down

    nextCounter: 0,             // Increments each time next() is called. a.k.a. 'SentChunks' ? 
    returnCounter: 0,           // Increments each time next()'s callback function is called. a.k.a. 'ReceivedChunks'?
    handle: function (requestOptions, next) {
        var self = this;
        if (self.cancel) {
            self.log('cancelling before chunk sent');
            return;
        }
        if (next) {
            self.nextCounter++;
            next(requestOptions, function (returnObject, finalCallback, nextPostCallback) {
                self.returnCounter++;
                if (self.cancel) {
                    self.log('cancelling after chunk received');
                    if (self.nextCounter == self.returnCounter && self.onCancelComplete) {
                        self.onCancelComplete();
                    }

                    // REALLY ??? Is this the right way to stop the upload?
                    return;

                }
                if (nextPostCallback) {
                    nextPostCallback(returnObject);
                } else if (finalCallback) {
                    finalCallback(returnObject);
                }
            });
        }
    }, 
    log: function (msg) {
        if (this.loggingOn) {
            console.log('cancelUploadFilter: ' + msg + ' nc: ' + this.nextCounter + ', rc: ' + this.returnCounter);
        }
    },
};

You would use it when creating the blob service like this:

var blobService = azure.createBlobService().withFilter(cancelUploadFilter);

Then if you have an upload in progress you cancel it like so:

cancelUploadFilter.cancel = true;

// optional: if you want to know when all in-progress chunks have stopped: 
cancelUploadFilter.onCancelComplete = function () { console.log('Cancelling complete'); };


来源:https://stackoverflow.com/questions/47762970/how-to-cancel-an-upload-started-with-blobservice-createblockblobfrombrowserfile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!