Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(iroh-bytes)!: refactor downloader queue and add progress reporti…
…ng (#2085) ## Description This PR contains changes to the downloader: * Remove the `Role::Provider` vs `Role::Candidate` distinction. We added this back when we did not have content propagation in docs, and it now does not make much sense for our architecture. Either we know/assume a node has something, or not. The "inbetween" state did not make sense anymore IMO. * Rework the queuing logic to be based on a simple queue of pending downloads. Before, if a download could not be started because the concurrenty limits were reached, the download was considered failed and inserted, with a delay, into the retry queue. Now, if a download cannot be started, we just wait until a slot frees up, and then start it. Note that the queue is, for now, quite simple - if the next download in the queue cannot be started (e.g. because all provider nodes are currently busy with other downloads), we do not try to start the second-top download in the queue, but instead wait until a slot is freed up. We could certainly optimize this by "jumping the queue" in certain cases, this would however also need more logic to make sure that downloads cannot be "forgotten". Therefore, for now the queue is handled strictly in order. * The retry behavior is refactored: We now retry nodes (not downloads as before) up to a retry limit, with an increasing timeout. If a download can only proceed with a retrying node, it is parked and the next item in the queue is processed. The download is unparked if the retrying node successfully connects. * Add progress reporting to downloads managed through the downloader. For this I wrote a `SharedProgress` handler that allows to subscribe to already running downloads: If an intent is registered for hash A, and this download is started, and while it is running, another intent is registered for the same hash, it will now receive an `DownloadProgress::InitialState` which contains a `TransferProgress` which functions as a reducer for the progress events This can be used from the client even, and further events can be reduced/merged into that struct. The PR contains a test for this concurrent progress reporting. * Expose the downloader in the iroh node. Download requests via the RPC API can now set a `DownloadMode` enum either to `Direct` or to `Queued`: the former will behave as currently (issue an iroh-bytes request directly, without a queue or concurrency limits) and the latter will add the download to the downloader queue. ## Breaking changes Changes in `iroh`: * The `BlobDownloadRequest` has a new field `mode` to select between direct and queued downloads, and now contains a list of `nodes` in place of a single `node` before Changes in `iroh_bytes`: * `Role` enum is removed * `Downloader::queue` now takes a `DownloadRequest` with more options than before * `DownloadProgress` has a new variant `InitialState` which is emitted when attaching to an already-running download * `ConcurrencyLimits` gained a new field Other changes: * `SetTagOption` was moved from `iroh` to `iroh-bytes` ## Notes & open questions * Another followup improves content downloading in docs: #2127 . * A few more tests around the queuing behavior would be great * I have a partially done followup which adds a hook for content discovery to the downloader <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist - [x] Self-review. - [x] Documentation updates if relevant. - [x] Tests if relevant. --------- Co-authored-by: Friedel Ziegelmayer <[email protected]>
- Loading branch information