I'm running a small console app that makes some web service calls asynchronously. As you know, this involves a callback method being called once the async method is complete.
This app was previously doing synchronous calls and using EntLib 5.0 to apply an exception handling policy to all of the app. The call was quite simple:
ExceptionManager em = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
try
{
// Call main work method
}
catch (Exception ex)
{
em.HandleException(ex, "Main Policy");
WriteErrorToConsole(ex);
}
Nice, concise, and in one place. But now I have an async callback, and it's not in the same stack.
In order to achieve consistent error handling, do I need to repeat this pattern in my callback method? If I had multiple async calls and callback methods, would I have to do it in every single method, or is there some way to apply an EntLib error-handling policy to all of them?
Related
I have an COM STA, that hosts an ICoreWebView2.
I try to get the complete HTML block and I found a documentation to achieve this with a script. Here my code:
hr = m_spWebView->ExecuteScript(L"document.body.outerHTML",
Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
[&val](HRESULT hr, LPCWSTR result) -> HRESULT
{
if (SUCCEEDED(hr))
val = result;
return S_OK;
}
).Get()
);
This code works, but it is executed asynchronous. So it takes some time to get the result. In fact I can see that the result arrives when the message pump is executed the next time (as I expect for an STA).
In C# I would use an await to wait for the completion.
But using C++ there is nothing like this. Using an event wouldn't work, because I have an STA I would block the thread and the answer will never arrive.
Is there any way to call a function that waits for the completion in C++? Or another help would be to use ExecuteScript synchron.
You have to implement an IDispatch interface (COM stuf), and add it with:
m_spWebView->AddHostObjectToScript(L"host", &disp);
Then you let JavaScript call it when the documment is loaded.
struct CDispatch : IDispatch
{
...
} cdisp;
You will get the HTML as a parameter in a Invoke call. Don't need to worry about the other methods, just confirm for IID_IDispatch in QueryInterface and watch for the Invoke.
window.chrome.webview.hostObjects.host(document.body.outerHTML);
I tried here and managed to do what you are willing to do.
If you have an STA then rather than explicitly waiting for completion, you can start your message loop or return back and allow your message loop to continue processing messages.
If you need to block execution and process messages without returning back to your message loop, you can try using CoWaitForMultipleHandles with COWAIT_DISPATCH_WINDOW_MESSAGES to ensure you process window messages which is necessary for WebView2 callbacks to execute. However, this can open up your app to reentrancy or other synchronization issues and depending on how the rest of your app deals with this, could be a problem.
Generally the better solution is to return back to your message loop.
Certificate validation in general requires asynchronous operations such as: OCSP/CRL fetch.
On the other hand, the callback from SSL_CTX_set_cert_verify_callback expects a synchronous result:
1 (success) / 0 (failure). (reference).
I find it kind of odd that any validation of this type is expected to be synchronous.
Is there an alternative API for certificate chain validation that supports asynchronous operations?
In theory I think you should be able to use the OpenSSL ASYNC API to do this. Normally this is used by asynchronous capable engines, but I don't see why it wouldn't also work in applications.
Firstly you would need to put your SSL object into ASYNC mode using the function call SSL_set_mode() and specifying SSL_MODE_ASYNC. You can also do this at the SSL_CTX level using SSL_CTX_set_mode(). See:
https://www.openssl.org/docs/man1.1.1/man3/SSL_set_mode.html
Once that is done you need to ensure your application is prepared to handle the return value SSL_ERROR_WANT_ASYNC from any call to SSL_get_error(). See:
https://www.openssl.org/docs/man1.1.1/man3/SSL_get_error.html
Your application can then implement a callback in the normal way via SSL_CTX_set_cert_verify_callback. If it needs to temporarily pause operation to wait for some asynchronous operation to complete then the callback should call ASYNC_pause_job(). See:
https://www.openssl.org/docs/man1.1.1/man3/ASYNC_pause_job.html
This will have the effect of control returning to your main application and SSL_get_error() will return SSL_ERROR_WANT_ASYNC. You will need to implement some mechanism for your application to know when asynchronous processing is complete. When it is, then simply retry the SSL I/O call that was previously paused. Note: this must occur on the same thread that the original call was made from. Your callback will then resume from the point at which it previously paused.
I am doing a POC on using the AWS-cpp-sdk
For which I wrote a simple program to send messages to the SQS queue.
I am using the SendMessageAsync method to send the messages like below.
sqsClient->SendMessageAsync(sendMessageRequest, &sendMessageCallBack);
My program crashes since my program is exiting before the async method returns and Aws::ShutdownAPI(options); terminates the threads created by the Async method call.
I found that the AWS-sdk for JAVA suggests the following for exactly this scenario.
`
/**
* Shuts down the client, releasing all managed resources. This includes
* forcibly terminating all pending asynchronous service calls. Clients who
* wish to give pending asynchronous service calls time to complete should
* call getExecutorService().shutdown() prior to calling this method.
*/
#Override
public void shutdown() {
super.shutdown();
executorService.shutdownNow();
}`
I am unable to find something equivalent in the AWS cpp SDK.
Can someone suggest what would be the best way to fix this issue.
You are responsible for making sure your requests are done before calling ShutdownAPI(). This is usually only an issue in contrived "sample app" sorts of scenarios where you are performing the operation directly inside your main() function. You also need to make sure the SQS client is deleted before ShutdownAPI is called.
On option is to use a std::condition_variable(semaphore) to synchronize before the exit. You can pass the semaphore to your callback and notify_one() at the end of the callback. Then, before shutdown you can call wait() on the semaphore.
I am writing an application that does multiple socket operations fairly consistently, and have a event messaging system similar to the javascript paradigm ( eventlistener.on(, ) / eventlistener.emit( ) ). I output some debug information from inside an async call that appends a TextBlock xaml element with the debugging information. When i emit the same event outside an async function, it works fine. I have wrapped my event on/emit calls with mutexes, which I assumed would be good enough to allow me to write to the TextBlock.
To visualize the event process:
[class]->listener->emit(< type>,< data>)->[Dispatcher]->[Listeners(< type>)]->lambda([class],< data>)
I'm not familiar enough with WinRT's async functions and the Windows 8 UI/Metro/Modern ideologies to know if there is a special way for me to append the TextBlock from a thread, or if there is a better way to go about this.
In short, is it possible to append a Textblock from an async function, and if so, do i need to do anything special?
There should be nothing preventing you from updating a TextBlock from an async function as long as the update is on the UI/dispatcher thread. The async function calls on a specific thread usually end on the same thread.
I have an API which sends/receives request/data from the serve in an asynchronous manner. The API comes with request functions and their corresponding callbacks.
I intend to use this API but a single function in my application can send multiple asynchronous requests to the server before it starts doing anything on its own. Is there any framework to manage composite asynchronous functions.
An example would be
void doSomething()
{
sendRequestDataItem1(); //receives result in getDataItem1()
sendRequestDataItem2(); //receives result in getDataItem2()
sendRequestDataItem3(); //receives result in getDataItem3()
//this function can either be a composite handler or something else
NowDoSomethingMore();
}
Thanks
Shiv
I would recommend boost::signals, it is pretty easy to use.
If you need thread safety (guessing?) boost::siganals2 is a good place to start.