Open sigfrid696 opened 4 years ago
Don't call CloseWhenReady() here. Call it in the main() function if you need to prevent it from exiting the application before the rest operations are done.
Hello, I tried you solution, but if I move CloseWhenReady() in main function at the end, then the list is always empty after the call to GetImages method.
Then I tried in another way. I don't need the function to be asynchronous, because I need to wait the call to GetImages before doing other things and moving ahead in the code. So I tried using the current thread instead of creating a new one. I changed the code in this way (as in another your tutorial).
client = restc_cpp::RestClient::CreateUseOwnThread();
and
std::list<OCRModels::Image> OCRAPIClient::GetImages(std::string vid)
{
std::string completeUrl = url + "/" + REST_GETIMAGES + "/" + vid;
std::list<OCRModels::Image> images;
client->Process([&](restc_cpp::Context& ctx) {
try {
SerializeFromJson(images,
restc_cpp::RequestBuilder(ctx)
.Get(completeUrl)
.Header("OCR-Client", "RESTC_CPP")
.Execute());
}
catch (std::exception ex)
{
std::cerr << "Error calling " << completeUrl << " : " << ex.what() << std::endl;
}
client->CloseWhenReady(true);
});
//client->CloseWhenReady(true);
// Start the io-service, using this thread.
client->GetIoService().run();
return images;
}
Is my understanding correct ? Is this using only the main current thread and not creating another thread ? No luck also in this case. The first call always works good giving back the correct list of images. Then the next calls return an empty list...
CloseWhenReady is used to tell the library to finish whatever it is doing and then quit. It can be used to hold the main thread off until the requests finish. But if you have more work, don't call it at all.
If you have more work, just make sure that the main thread don't exit the main() function, or use the main thread to handle the IO. Don't call CloseWhenReady() until you have finished all your requests.
CloseWhenReady is used to tell the library to finish whatever it is doing and then quit. It can be used to hold the main thread off until the requests finish. But if you have more work, don't call it at all.
If you have more work, just make sure that the main thread don't exit the main() function, or use the main thread to handle the IO. Don't call CloseWhenReady() until you have finished all your requests.
Ok I understand. I supposed that calling CloseWhenReady() function was the way to wait for the requests to be executed. If I remove it, the thread doesn't wait for each request to end, so each result is always empty. How am I supposed to wait for each request to end and then collect the results ? Is there any other function to call ? This is not clear to me.
I would like to go synchronous for my needs, is the last code I posted the right way ? It doesn't seem ok to me because I don't have a way to wait for the lambda to be executed if I remove CloseWhenReady call, so the list of images is always empty...
The solution could be to use ProcessWithPromise but it seems to work only with coroutine. How can I make
client->GetIoService().run();
terminate in a synchronous scenario without calling
client->CloseWhenReady(true);
Sorry for so many question but maybe now I'm near to the solution Many thanks for your attention
The point with asynchronous programming is not to wait. You get the result inside the lambda, and while the request is pending, your threads are free to do away with other work. If you /really/ want to wait on the outside, you can use a std::future for that.
The point with asynchronous programming is not to wait. You get the result inside the lambda, and while the request is pending, your threads are free to do away with other work. If you /really/ want to wait on the outside, you can use a std::future for that.
Sometimes it is a good choice to do synchronous requests, depending on the overall architecture of the system... Very last question, can I consider the calls to the methods Process and ProcessWithPromise thread safe (i.e. can the same RestClient object be called by different threads) or do I have to protect calls externally ? Thanks
This is an interesting question actually: do I have to protect the RestClient object with a mutex when I call ProcessWithPromise()?
Hello,
first of all thanks for your beautiful library.
I have the following problem, maybe I'm doing something wrong but I don't understand what...
This is my code, very simple and taken from one of the tutorials.
I create at startup the client in this way: I register my url and then create client.
Then I start calling a Rest API (which is tested from other not c++ clients and has no working problems) which returns a list of objects, Image objects in this case. This is the method that I call several times in a loop with different "vid" parameter passed to the function:
I understand that this is calling the lambda in a co-routine managed by boost library.
The first call always works good giving back the correct list of images. Then if I try another call in the loop, the lambda is never called again... If I destroy the client object before every call everything works good.
Did I miss something ? What's wrong in my code ?
Thank You, your work is much appreciated.
Best Regards
Alessandro