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

question on catch exception for async operations #402

Open
sherlockwu opened this issue Jun 23, 2021 · 9 comments
Open

question on catch exception for async operations #402

sherlockwu opened this issue Jun 23, 2021 · 9 comments

Comments

@sherlockwu
Copy link

Hi all,

I have a question related to catching exception for azure blob async upload operations.
Here is my sync version: (upload if not exist)

try {
        azure::storage::cloud_storage_account storage_account = azure::storage::cloud_storage_account::parse(
                storage_connection_string);
        azure::storage::cloud_blob_client blob_client = storage_account.create_cloud_blob_client();
        azure::storage::cloud_blob_container container = blob_client.get_container_reference(U("my-sample-container"));

        azure::storage::cloud_block_blob blob4 = container.get_block_blob_reference(U("my-blob-4"));
        azure::storage::access_condition condition4 = azure::storage::access_condition::generate_if_not_exists_condition();
        azure::storage::blob_request_options options4;
        azure::storage::operation_context context4;
        blob4.upload_text(U("test new overwrite text"), condition4, options4, context4);
    }
    catch (const std::exception &e) {
        std::cout << U("Error: ") << e.what() << std::endl;
    }

The catch part will catch the exception if the blob already exists.

My question is:

  1. how should I catch the exception for upload_text_async() ? simply replace upload_text by upload_text_async cannot catch the exception.
  2. is there a way I can get the return "message" of async or sync operations, instead of by throwing exceptions?

Thank you,
Kan

@Jinming-Hu
Copy link
Member

how should I catch the exception for upload_text_async() ? simply replace upload_text by upload_text_async cannot catch the exception.

auto async_task = blob4.upload_text_async(U("test new overwrite text"), condition4, options4, context4);
try {
  async_task.get();  // block until the task is finished.
}
catch (const std::exception& e) {
  std::cout << U("Error: ") << e.what() << std::endl;
}

@sherlockwu
Copy link
Author

Thanks for your reply!

Uhm, would that piece of code become sync upload then?

@Jinming-Hu
Copy link
Member

is there a way I can get the return "message" of async or sync operations, instead of by throwing exceptions?

The return type for upload_text and unpload_text_async is void, so there isn't any "message".

Take cloud_blob::exists() for example, the sync version returns a bool. So if the blob actually exists, that function returns true. If the blob doesn't exists, the function returns false. If any error happens (like authentication error), the function will throw.
For async version, calling .get() on the returned task will return true or false or throw.

@Jinming-Hu
Copy link
Member

Jinming-Hu commented Jun 24, 2021

Uhm, would that piece of code become sync upload then?

In your sample code, yes. Because there's only one task. You can start a bunch of asynchronous tasks and then wait for them in one thread, like

std::vector<pplx::task<T>> tasks;
tasks.emplace_back(an_async_function());

for (auto& t: tasks) {
    t.get();
}

Note that it's your responsibility to observe every potential exception in async task. So if you're pretty sure some async task won't throw, you don't have to call .get().

@Jinming-Hu
Copy link
Member

@sherlockwu BTW, this project has been deprecated in favor of our new version of storage SDK. So if you're starting a new project, you may want to try the new sdk.

@sherlockwu
Copy link
Author

Thanks for your reply.

Perhaps I could talk more about our expected behaviors.

We'd like to

  1. async upload some blobs (if they do not exist).
  2. then know whether the uploads succeed or not (not may because blobs already exist);
  3. no matter succeed or not, we'd like to do some follow-up work upon a upload complete.

Now, I'm using .then() to implement the follow-up works. However, turns out we cannot know the uploads succeeded or not.
What would you suggest us to implement with the APIs? thanks

Thanks for telling us about storage SDK. Would our need be easier to implement with azure-sdk? Thanks

@Jinming-Hu
Copy link
Member

@sherlockwu

Every API has an overload which takes an access_condition as parameter, where you can set if-not-exist condition, so that the operation will fail and throw exception if the blob already exists. (Which I see you already did in your sample code)

In the .then() continuation task, you can tell if the last operation succeeded or not by checking if there's an exception. Like

auto t = blob4.upload_text_async(U("test new overwrite text"), condition4, options4, context4).then([](pplx::task<void> previous_task) {
  try {
    previous_task.get();
  }
  catch (azure::storage::storage_exception& e)
  {
    // failed, do clean up work here
  }
  // not failed, do other work
});
t.wait();  // This waits for the continuation task (defined by the lambda).

@Jinming-Hu
Copy link
Member

Would our need be easier to implement with azure-sdk?

The new SDK only supports synchronous API, which is much easier to use.

Asynchronous task in this sdk is less easy to comprehend and is error-prune. In addition, although the API interface is asynchronous, it uses a thread-pool under the hood, so there's really no performance gain here. Actually our new SDK has much better performance than this old sdk.

@sherlockwu
Copy link
Author

Got you.

That sample code looks like what we indeed need.
Let me have a try and get back to you.

Thanks a lot for the help.

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

No branches or pull requests

2 participants