Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to stop createBlockBlobFromStream while it is uploading #317

Closed
georgesmarkus opened this issue Jun 23, 2017 · 4 comments
Closed

How to stop createBlockBlobFromStream while it is uploading #317

georgesmarkus opened this issue Jun 23, 2017 · 4 comments
Assignees

Comments

@georgesmarkus
Copy link

Hi,
I started to use the Azure storage client library, the question is, and I am now using createBlockBlobFromStream to upload large files.
The question is: The user may be willing to cancel a file at any time while uploading, is there a way to cancel the file from being uploaded, in other words, to abort createBlockBlobFromStream background execution
Regards

@XiaoningLiu
Copy link
Member

@georgesmarkus Sorry for that, there is no API to cancel uploading directly. But for every blobService object, we can create a filter and can stop the uploading in the filter. The filter will be executed before and after every time a request in the stream performs.

Please refer to the following link about creating a custom filter:
http://azure.github.io/azure-storage-node/StorageServiceClient.html#withFilter

After creating a filter, pass the filter to the blobService object with withFilter()

var blobService = azure.createBlobService().withFilter(myFilter)

@tonygomez
Copy link

@XiaoningLiu filter I see your work-around using a filter but could not get it to work for me. I upload a large queue of files (varying sizes). A much simper solution would be a return handle/object with an abort method. Is this at least on the roadmap?

@rjk
Copy link

rjk commented Dec 12, 2017

I second this request. It'd be very helpful to be able to cancel in-progress uploads.

Perhaps a filter could be provided that has a cancel() method, since it's quite hard to get your head around the withFilter() implementation. Even more so if I need to do something to combine it with retry filters.

Or can anyone provide a simple example of a cancel-able filter?

@rjk
Copy link

rjk commented Dec 13, 2017

Here's my 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'); };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
@rjk @tonygomez @EmmaZhu @XiaoningLiu @vinjiang @georgesmarkus and others