-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
specific async pattern implementation query #930
Comments
Hello @borisu , You can do it with Here is example: Declare Lock and CV to share between oatpp coroutine and some other thread: oatpp::async::Lock lock;
oatpp::async::ConditionVariable cv; Coroutine: class TestCoroutineWait : public oatpp::async::Coroutine<TestCoroutineWait> {
private:
std::shared_ptr<Resource> m_resource;
oatpp::async::LockGuard m_lockGuard; // Use async::LockGuard to guard the lock
oatpp::async::ConditionVariable* m_cv;
public:
TestCoroutineWait(std::shared_ptr<Resource> resource,
oatpp::async::Lock* lock, // pass async::Lock to coroutine
oatpp::async::ConditionVariable* cv) // pass async::ConditionVariable to coroutine
: m_resource(resource)
, m_lockGuard(lock)
, m_cv(cv)
{}
Action act() override {
return m_cv->wait(m_lockGuard, [this]{return m_resource->counter == 100;}) // long wait until counter == 100
.next(yieldTo(&TestCoroutineWait::onReady));
}
Action onReady() {
OATPP_ASSERT(m_lockGuard.owns_lock()) // Now coroutine owns the lock
return finish();
}
}; Other thread: std::thread t([&resource, &lock, &cv] {
{ // very long operation
std::lock_guard<oatpp::async::Lock> guard(lock);
for(int i = 0; i < 100; i++) {
resource->counter++;
}
}
cv.notifyAll();
}) Note1: you can find working example here - https://github.com/oatpp/oatpp/blob/master/test/oatpp/core/async/ConditionVariableTest.cpp Note2: It's possible to implement it with just oatpp::async::CoroutineWaitList but it's cleaner to use do it this way. There are details that you may miss when working with CoroutineWaitList. Note3: Always use thread pool in case you are spawning threads from coroutine. Note4: Make sure to have latest master as |
Thanks a lot , I will try it and ccomment here with results |
Worked well. Thanks Indeed I needed to upgrade to 1.3-latest as I understand it was relatively new additions. |
@lganzzzo I am using vcpkg for the project and it seams like oatpp::async::ConditionVariable is still not vailable there, when are you (if at all) planning to update vcpkg with new 1.4.0 package? |
In order to integrate oatpp into the project I need to follow rigid asynchronous threading model. Specifically speaking, on http request callback I cannot return the result immediately, I need to transfer control to other module (running in different thread, or even different network service) and then it will supply me back the result.
I can implement it with sync API by blocking the response till mentioned module finishes the job but it will consume the thread for the time the request being processed, which I guess make handling many parallel requests inefficient. So I need to release the control immediately and then somehow inform the oatpp that the response is ready and it needs to be sent to the channel the http request was received from. But looking into oatpp API i just can't get a clue how to write such thing. I looked into coroutines and IO_READ/WRITE actions tasks but couldn't get my head around the details. Any help will be much appreciated.
The framework in general has the following form
oatpp::HttpRequestHandler::handleAsync(request)
{
enqueu_3rdparty_request() // send the async request to the unknown module
return ??? // <-- return action which just waits for the response
}
Unknown3rdPartyModule::onRequest()
{
// do some very long work
// do something that wakes up the oapp action in "waiting list" and continues with the supplied resonse
{
The text was updated successfully, but these errors were encountered: