2016-04-19 20:41:59 +00:00
|
|
|
/*
|
|
|
|
* This file Copyright (C) 2016 Mnemosyne LLC
|
|
|
|
*
|
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
|
|
#include "RpcQueue.h"
|
|
|
|
|
2020-09-09 14:24:39 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
|
|
|
RpcQueue::Tag RpcQueue::next_tag = {};
|
2020-07-29 16:56:23 +00:00
|
|
|
|
2021-08-15 09:41:48 +00:00
|
|
|
RpcQueue::RpcQueue(QObject* parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, tag_(next_tag++)
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2020-10-31 18:56:12 +00:00
|
|
|
connect(&future_watcher_, &QFutureWatcher<RpcResponse>::finished, this, &RpcQueue::stepFinished);
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void RpcQueue::stepFinished()
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
RpcResponse result;
|
2016-04-19 20:41:59 +00:00
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
if (future_watcher_.future().isResultReadyAt(0))
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
result = future_watcher_.result();
|
|
|
|
RpcResponseFuture future = future_watcher_.future();
|
2016-04-19 20:41:59 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
// we can't handle network errors, abort queue and pass the error upwards
|
|
|
|
if (result.networkError != QNetworkReply::NoError)
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
assert(!result.success);
|
2016-04-19 20:41:59 +00:00
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
promise_.reportFinished(&result);
|
2017-04-19 12:04:45 +00:00
|
|
|
deleteLater();
|
|
|
|
return;
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
// call user-handler for ordinary errors
|
2020-05-27 21:53:12 +00:00
|
|
|
if (!result.success && next_error_handler_)
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
next_error_handler_(future);
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
// run next request, if we have one to run and there was no error (or if we tolerate errors)
|
2020-05-27 21:53:12 +00:00
|
|
|
if ((result.success || tolerate_errors_) && !queue_.isEmpty())
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
runNext(future);
|
|
|
|
return;
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
}
|
2017-04-19 12:04:45 +00:00
|
|
|
else
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
assert(!next_error_handler_);
|
|
|
|
assert(queue_.isEmpty());
|
2016-04-19 20:41:59 +00:00
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
// one way or another, the last step returned nothing.
|
|
|
|
// assume it is OK and ensure that we're not going to give an empty response object to any of the next steps.
|
|
|
|
result.success = true;
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
promise_.reportFinished(&result);
|
2017-04-19 12:04:45 +00:00
|
|
|
deleteLater();
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-20 16:02:19 +00:00
|
|
|
void RpcQueue::runNext(RpcResponseFuture const& response)
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
assert(!queue_.isEmpty());
|
2016-04-19 20:41:59 +00:00
|
|
|
|
2020-06-05 19:02:11 +00:00
|
|
|
RpcResponseFuture const old_future = future_watcher_.future();
|
2017-07-15 05:46:31 +00:00
|
|
|
|
2020-11-02 01:13:32 +00:00
|
|
|
for (;;)
|
2017-07-15 05:46:31 +00:00
|
|
|
{
|
2020-05-27 21:53:12 +00:00
|
|
|
auto next = queue_.dequeue();
|
|
|
|
next_error_handler_ = next.second;
|
|
|
|
future_watcher_.setFuture((next.first)(response));
|
2017-07-15 05:46:31 +00:00
|
|
|
|
2020-06-05 19:02:11 +00:00
|
|
|
if (old_future != future_watcher_.future())
|
2017-07-15 05:46:31 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-05-27 21:53:12 +00:00
|
|
|
if (queue_.isEmpty())
|
2017-07-15 05:46:31 +00:00
|
|
|
{
|
|
|
|
deleteLater();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
void RpcQueue::run()
|
2016-04-19 20:41:59 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
runNext(RpcResponseFuture());
|
2016-04-19 20:41:59 +00:00
|
|
|
}
|