#include "ApiBatch.hpp" namespace geopro::net { ApiBatch::ApiBatch(QList 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(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-fast:abort 其余在飞 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