blob: b77068465e52f5704678c9a72549addf05b371aa [file] [log] [blame]
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef QUICHE_QUIC_MOQT_MOQT_FETCH_TASK_H_
#define QUICHE_QUIC_MOQT_MOQT_FETCH_TASK_H_
#include <utility>
#include <variant>
#include "absl/status/status.h"
#include "quiche/quic/moqt/moqt_messages.h"
#include "quiche/quic/moqt/moqt_object.h"
#include "quiche/common/quiche_callbacks.h"
namespace moqt {
// A handle representing a fetch in progress. The fetch in question can be
// cancelled by deleting the object.
class MoqtFetchTask {
public:
using ObjectsAvailableCallback = quiche::MultiUseCallback<void()>;
// The request_id field will be ignored.
using FetchResponseCallback = quiche::SingleUseCallback<void(
std::variant<MoqtFetchOk, MoqtFetchError>)>;
virtual ~MoqtFetchTask() = default;
// Potential results of a GetNextObject() call.
enum GetNextObjectResult {
// The next object is available, and is placed into the reference specified
// by the caller.
kSuccess,
// The next object is not yet available (equivalent of EAGAIN).
kPending,
// The end of fetch has been reached.
kEof,
// The fetch has failed; the error is available via GetStatus().
kError,
};
// Returns the next object received via the fetch, if available. MUST NOT
// return an object with status kObjectDoesNotExist.
virtual GetNextObjectResult GetNextObject(PublishedObject& output) = 0;
// Sets the callback that is called when GetNextObject() has previously
// returned kPending, but now a new object (or potentially an error or an
// end-of-fetch) is available. The application is responsible for calling
// GetNextObject() until it gets kPending; no further callback will occur
// until then.
// If an object is available immediately, the callback will be called
// immediately.
virtual void SetObjectAvailableCallback(
ObjectsAvailableCallback callback) = 0;
// One of these callbacks is called as soon as the data publisher has enough
// information for either FETCH_OK or FETCH_ERROR.
// If the appropriate response is already available, the callback will be
// called immediately.
virtual void SetFetchResponseCallback(FetchResponseCallback callback) = 0;
// Returns the error if fetch has completely failed, and OK otherwise.
virtual absl::Status GetStatus() = 0;
};
// A fetch that starts out in the failed state.
class MoqtFailedFetch : public MoqtFetchTask {
public:
explicit MoqtFailedFetch(absl::Status status) : status_(std::move(status)) {}
GetNextObjectResult GetNextObject(PublishedObject&) override {
return kError;
}
absl::Status GetStatus() override { return status_; }
void SetObjectAvailableCallback(
ObjectsAvailableCallback /*callback*/) override {}
void SetFetchResponseCallback(FetchResponseCallback callback) {
MoqtFetchError error;
error.request_id = 0;
error.error_code = StatusToRequestErrorCode(status_);
error.error_reason = status_.message();
std::move(callback)(error);
}
private:
absl::Status status_;
};
} // namespace moqt
#endif // QUICHE_QUIC_MOQT_MOQT_FETCH_TASK_H_