// vdm/task/download_task.hpp — internal: the task machine behind DownloadHandle, and the // narrow interface it uses to reach engine-owned resources (so this TU doesn't depend on // Engine::Impl). #ifndef VDM_TASK_DOWNLOAD_TASK_HPP #define VDM_TASK_DOWNLOAD_TASK_HPP #include #include #include #include "vdm/engine.hpp" #include "vdm/ids.hpp" #include "vdm/net/http_client.hpp" #include "vdm/net/probe.hpp" #include "vdm/rate/token_bucket.hpp" #include "vdm/segment/budget.hpp" #include "vdm/task/download.hpp" namespace vdm::task { using TimerId = std::uint64_t; // Implemented by Engine::Impl. Every method is safe to call from any thread. struct TaskHost { virtual ~TaskHost() = default; virtual net::HttpClient &http() = 0; virtual segment::SegmentBudget &budget() = 0; virtual rate::RateLimiter &limiter() = 0; virtual const Engine::Config &config() = 0; // One-shot timer. `fn` runs on the engine's timer thread. cancel_timer is a no-op if // it already fired or never existed. virtual TimerId schedule(SteadyTime at, std::function fn) = 0; virtual void cancel_timer(TimerId id) = 0; // Probe pool, outside the segment budget (ADR 0011 §5). virtual void probe(net::ProbeRequest req, std::function)> done) = 0; // The task reached a terminal state — drop it from the engine's registry. virtual void task_retired(TaskId id) = 0; }; // Create a task and begin it (probe or connect). The returned control block is what // DownloadHandle wraps (DownloadHandle{state}); the engine keeps its own copy so the task // outlives a caller that drops its handle. [[nodiscard]] std::shared_ptr create_task(TaskHost &host, TaskId id, DownloadSpec spec, DownloadCallbacks cbs); // Engine shutdown: stop every transfer and fire no further callbacks. Safe on nullptr. void quiesce_task(const std::shared_ptr &s); } // namespace vdm::task #endif // VDM_TASK_DOWNLOAD_TASK_HPP