geopro/src/net/ApiBatch.cpp

44 lines
1.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ApiBatch.hpp"
namespace geopro::net {
ApiBatch::ApiBatch(QList<IApiCall*> calls, Predicate isFailure, QObject* parent)
: QObject(parent), isFailure_(std::move(isFailure)) {
Q_ASSERT(!calls.isEmpty()); // 契约:至少一个 call空 batch 永不发 succeeded调用方会挂起
Q_ASSERT(isFailure_); // 契约:必须提供失败谓词(否则首个 finished 即 bad_function_call
responses_.resize(calls.size());
remaining_ = static_cast<int>(calls.size());
for (int i = 0; i < calls.size(); ++i) {
IApiCall* c = calls[i];
calls_.append(c);
QObject::connect(c, &IApiCall::finished, this, [this, i](const ApiResponse& resp) {
if (aborted_) return; // §5.0 入口守卫
if (isFailure_(resp)) {
aborted_ = true; // 此后 remaining_ 不再维护:迟到 finished 全被入口守卫挡掉
for (const auto& other : calls_) { // fail-fastabort 其余在飞
if (other) other->abort();
}
emit failed(i, resp);
deleteLater();
return;
}
responses_[i] = resp;
if (--remaining_ == 0) {
emit succeeded(responses_);
deleteLater();
}
});
}
}
void ApiBatch::abort() {
if (aborted_) return;
aborted_ = true;
for (const auto& c : calls_) {
if (c) c->abort();
}
deleteLater();
}
} // namespace geopro::net