Azure / azure-storage-cpp

Microsoft Azure Storage Client Library for C++
http://azure.github.io/azure-storage-cpp
Apache License 2.0
131 stars 147 forks source link

Question: how to undo upload_block for a non-existing blob so no empty blob is being created? #331

Closed yxiang92128 closed 4 years ago

yxiang92128 commented 4 years ago

I am trying to use upload_block and then upload_block_list to upload "chunks" of a blob and finalize it by calling "upload_block_list". The problem is that there is no "undo" mechanism to allow me cancel the operation without creating an empty blob with size 0. It seems when the upload_block call is made and empty sized blob object was created.

Is there a work around without the state of the blob being tracked on the client side? Basically I need to know whether the blob is a new object before the "upload_block_list" is being called and then on an undo request from the application, I can call "delete" to drop the blob without calling "upload_block_list".

Thanks for any hints.

Yang

Jinming-Hu commented 4 years ago

It seems when the upload_block call is made and empty sized blob object was created.

It's not the case, upload_block doesn't create blob. No matter with get_blob or list_blobs, you cannot see the blob before it's created with upload_block_list.

However you can track the state of those uncommitted blocks with get_block_list.

yxiang92128 commented 4 years ago

I put a gdb breakpoint after upload_block call without calling upload_block_list and it seems to have created a 0 sized block blob object right away. I can write up a test program to prove it if you'd like.

Thanks for looking into it.

Yang

Jinming-Hu commented 4 years ago

@yxiang92128 Please provide us with a test program. This would be a very severe issue if it's true.

yxiang92128 commented 4 years ago

@JinmingHu-MSFT I think you are correct. It does not create a 0 sized block blob. But I still need to check whether the block blob exists or not. I tried to do the following: auto existing_blocks = block_blob.download_block_list(azure::storage::block_listing_filter::all, azure::storage::access_condition::generate_if_exists_condition(), azure::storage::blob_request_options(), azure::storage::operation_context()); if (existing_blocks.size() > 0) { // append blocks } else { // insert a header block } But it throws a storage exception with HTTP code 404 instead of returning. I am using the access condition "generate_if_exists_condition" so I assume the operation will only perform if the resources exists. I tried with the default access condition as well.

Is there a quicker way to check whether a cloud_block_blob actually exists before an operation can be performed on it instead of try and catch an exception? I can try to do a list first but if the bucket contains a long list of blobs the performance would suffer.

Thanks for helping out,

Yang

Jinming-Hu commented 4 years ago

@yxiang92128

Is there a quicker way to check whether a cloud_block_blob actually exists before an operation can be performed on it instead of try and catch an exception?

Yes, there's a function exists() to check whether a blob exists.

download_block_list only throws 404 if the blob doesn't exist and there're no uncommitted blocks for this blob. This is by design.

yxiang92128 commented 4 years ago

works! thanks!