| // 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) override { | |
| 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_ |