core: add the download engine — task machine, DownloadHandle, Engine
Stage 8 of the CORE build order: the bodies behind the DownloadSpec / callback API reviewed in core/docs/engine-api-m1.md. Wires probe -> segment workers -> WriteBuffer -> SparseFile -> .veloxpart.meta -> retry/backoff -> SegmentBudget -> RateLimiter -> callbacks into one event-driven machine. - Engine (src/engine.cpp): owns HttpClient, Prober, SegmentBudget, RateLimiter and one timer jthread (min-heap of scheduled fns). start() builds a task and returns a DownloadHandle; ~Impl quiesces every task before joining the timer so no callback fires during teardown. - DownloadTaskState (src/task/download_task.cpp): one `mu` task lock; a shared_mutex over the worker map for the curl write path; callbacks collected under `mu` and fired after release via a separate deferred queue; weak_from_this() in every async hop. State machine over the CORE-owned EngineState subset, auto-pause on 401/407 and on a 200 where 206 was expected, validated resume via If-Range. - digest (src/task/digest.cpp): OpenSSL EVP hash_file() for the optional post-download checksum; links OpenSSL::Crypto PRIVATE. - Segmenter::release_segment(): hand a paused segment back to the pool unassigned so resume's assign_slot() picks it up instead of splitting a still-"assigned" range and orphaning its front half. - DownloadHandle now names the real control block (vdm::task:: DownloadTaskState, defined only in the engine TU) via a namespace-scope fwd decl and a public-but-effectively-engine-only ctor, replacing the nested State/friend pair. Every public signature is unchanged; DAEMON (vdm-79) confirmed sched/ names only the public API. Fixes found while building the end-to-end suite (tests/task/engine_test.cpp, 9 cases against tools/testserver, green under ASan/UBSan and TSan): - a dropped connection lost its unflushed WriteBuffer tail while advance() had already counted those bytes as done -> a retry resumed past an unwritten hole. Flush on the failure path. - when the byte counters hit total while other workers were still live, teardown dropped their buffered tails. Now: cancel them and let each worker's own seg_finished drain it (the `assembling` state), last one starts verification -- no cross-thread buffer access. - seg_head() let a 401 with credentials present abort before libcurl's resend; now it proceeds once and acts on the final status. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01HPPSGhiArbvQgwC2DNiURS
This commit is contained in:
+5
-1
@@ -6,6 +6,7 @@
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(CURL 8.0 REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
add_library(veloxcore STATIC
|
||||
src/util/error.cpp
|
||||
@@ -22,6 +23,9 @@ add_library(veloxcore STATIC
|
||||
src/meta/veloxpart.cpp
|
||||
src/segment/segmenter.cpp
|
||||
src/segment/budget.cpp
|
||||
src/task/digest.cpp
|
||||
src/task/download_task.cpp
|
||||
src/engine.cpp
|
||||
)
|
||||
add_library(velox::core ALIAS veloxcore)
|
||||
|
||||
@@ -38,7 +42,7 @@ target_compile_options(veloxcore PRIVATE
|
||||
-Wall -Wextra -Wpedantic -Werror
|
||||
)
|
||||
|
||||
target_link_libraries(veloxcore PUBLIC Threads::Threads CURL::libcurl)
|
||||
target_link_libraries(veloxcore PUBLIC Threads::Threads CURL::libcurl PRIVATE OpenSSL::Crypto)
|
||||
|
||||
# Later stages add: find_package(OpenSSL) for meta/ (streaming SHA-256 + resume CRC).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user