Apollo Download ManagerApollo Download Manager
On this page

Settings

Every Apollo Download Manager setting, what it does, and its bounds. They are sections of one settings document in the database, each read and saved through Database::section and Database::save_section, and checked first (the Section trait). Each setting is checked in Rust before it applies, whatever the screen allows.

The Settings screen

The screen (#30, src/features/settings/SettingsView.tsx) edits every section below except the window's look, which keeps saving through set_appearance so it never overwrites a panel width (the window).

  • Saved whole: set_settings checks every section first and saves none when one is refused (INVALID_INPUT); then it writes them all in one go, and applies them at once (velocity_core::settings::Settings, Manager::set_settings). The screen says "Saving…", then "Saved", or why it wasn't, and shows what is saved.

  • When each applies: at once, all of them. The engine's retries, timeouts, preallocation and write buffer apply to downloads that start or retry after the change; the connection budget, the queue, the limits and the torrent helper's settings apply to running ones too. None needs a restart.

  • Read with defaults: a section is read merged over its defaults, so settings an older Apollo Download Manager saved get the newer fields' defaults (V1's migrate_settings_json). A field this build doesn't know is refused, never dropped.

  • When the app starts: the saved settings are applied (Manager::apply_saved_settings), and the torrent helper starts with its own. A failure is logged, and the defaults hold for what couldn't be read.

  • Reset to defaults asks first, and keeps the download folder (V1's).

  • What the build can't do is disabled with the reason (below). Today's engine does everything the screen offers, Metalink included (#54).

Engine

EngineSettings in crates/velocity-core/src/transfer.rs (#30), the engine section: V1's retry, timeout, connection-budget and disk settings, as ADR-0005 mapped them. The engine gets them through set_engine_settings (transfer contract version 14); its supervisor gives them to a new engine after a restart.

SettingDefaultBoundsV1's
failuresInARow51 to 100max_tries
maxRetryWaitSecs601 to 600retry_wait_secs
stalledAfterSecs155 to 600lowest_speed_limit_kib: time without data, or under the engine's 1 KiB/s floor (#292)
resetAfterSecs305 to 3600, never below stalledAfterSecstimeout_secs
connectTimeoutSecs301 to 300connect_timeout_secs (HTTP, HTTPS and FTP; SFTP keeps its own)
downloadRetries20 to 10app_retries
connectionBudget481 to 256connection_budget
preallocationsparsenone, sparse or fullfile_allocation
writeBufferMib21 to 64, per connectiondisk_cache_mib
  • Preallocation: sparse marks the part file sparse on Windows (#42's measurement), none doesn't, and full sets the file's length as soon as its size is known, so a disk too small fails at once.

  • Write buffer: how many fetch events, of at most 1 MiB each, a connection may have waiting for the writer.

Advanced and new torrents

AdvancedSettings (the advanced section) and NewTorrentSettings (newTorrents) in crates/velocity-core/src/settings.rs (#30).

SectionSettingDefaultBounds
advancedForget servers (a button, not a saved setting)—Forgets what downloads learned about servers (forget_learned_servers, #325)
globalDownloadLimitKib0: none0, or at least 1 KiB/s (#49). Direct downloads only: torrents have their own downloadLimit (TORRENTS.md, #312)
enableBittorrenton (V1's)Off refuses torrents and magnet links with PROTOCOL_DISABLED
enableMetalinkoff (V1's)Offered when the engine reads Metalink, as it does since #54
userAgentnull: ApolloDownloadManager/<version>At most 256 bytes, no control characters; for downloads added after it
newTorrentschooseFilesForMagnetsoffThe Add dialog's "Choose files before downloading"
seedingneverAs a torrent's seeding policy (TORRENTS.md)
uploadLimitKib0: noneThe Add dialog's upload limit

Browser

BrowserSettings (the browser section) in crates/velocity-core/src/browser/mod.rs (#65), V1's. The screen's Browser section also registers the native host with each browser (BROWSER_EXTENSION.md).

SettingDefaultWhat it does
acceptRequestsonOff refuses links from the extension (DISABLED); the browser then downloads them
confirmBeforeAddingonA link opens the Add dialog. Off adds it at once, unless it is a torrent, a magnet link, a taken name or a link added before

The torrent helper's own settings are the torrent section, TorrentSettings (TORRENTS.md); the screen shows them with the helper's port and port mapping (get_torrent_network).

Proxy

ProxySettings (the proxy section) in crates/velocity-core/src/proxy.rs (#192, ADR-0008). The screen's Proxy section edits it. It holds no password.

SettingDefaultBounds
kindnonenone, http, https or socks5
hostemptyWith a proxy: a DNS name (an international one kept in its ASCII form, as links are), an IPv4 address, or an IPv6 address in brackets; no scheme, port or login. Without one, kept as typed
port80801 to 65535 with a proxy
userNameempty: no loginWhat a login may have: no : or control character
rememberPasswordoffKeep the password in the system keychain (ADR-0015)
  • The password is set on its own (set_proxy_password) and never comes back to the window, which only learns whether one is set (get_proxy_password_set). It is held in memory, and saved in the keychain only while rememberPassword is on; turning it off deletes it there (PO decision on #192). A keychain that refuses is said (KEYCHAIN_UNAVAILABLE), and the password is still used until the app closes.

  • What it covers: every direct download (HTTP, HTTPS, FTP, SFTP) that starts, resumes or retries after a change, and the torrent helper at once. SFTP and torrents can't use an HTTPS proxy: SFTP downloads fail with a message saying so, and no torrent starts (PROXY_UNSUPPORTED). How each engine uses it is in ENGINE_INTERNALS.md and TORRENTS.md.

  • When the app starts the torrent helper gets the proxy, with a remembered password, before anything else, and the transfer engine before the first download starts.

The window

Performance

Performance profiles are limits for the adaptive engine (ADR-0005, #57), not V1's aria2 option sets. Within a profile's limits, a download opens every connection it may use, a step at a time, and the engine drops those that don't make it faster (ENGINE_INTERNALS.md, #47, #221). A server that gains nothing from more connections gets fewer.

ProfileConnections, per download and per serverSmallest pieceNotes
Conservative220 MiBV1's values, for servers or networks that dislike many connections
Balanced, the default81 MiBThe engine's values before profiles existed, so nothing changed without a measurement
Maximum161 MiBV1's connections. More than 8 only helps a server that gives each connection its own speed
CustomThe user's: 1 to 16The user's: 1 to 1024 MiBV1's max_connection_per_server and min_split_size_mib. aria2's split count is gone, as Apollo DM splits by itself
  • All profiles keep a connection at the same 10% loss for now: one whose loss would slow the download by 10% or more stays (#221; #57 set one threshold for every profile). Whether Conservative and Maximum should use other thresholds is for #77's measurements.

  • The smallest piece applies to downloads that start after the profile changes. The connection cap applies at once: a lower one holds running downloads back, which their details then say ("the performance profile allows no more to one server").

  • The shared budget for all downloads together stays 48 connections, V1's connection_budget (#47).

  • In code: PerformanceSettings in crates/velocity-core/src/performance.rs maps a profile to EngineLimits. Manager::set_performance applies it, and new downloads ask for at most its connections (Manager::connections_for_new_downloads). The engine takes the limits through set_engine_limits (ENGINE_CONTRACT.md).

  • Removed, as ADR-0005 decided: "allow mid-download tuning" (Apollo Download Manager changes connections without restarting a download), and the aria2 optimizer.

Queue

QueueSettings in crates/velocity-core/src/queue.rs (#50):

SettingDefaultBounds
maxConcurrentDownloads2 (3 before 0.2.0, #351)1 to 32
startImmediatelyon—
restartOnNetworkonA download that failed because there was no network waits for it, and starts again from its bytes when the system's network changes (#318, ADR-0019)
schedule.enabledoff—
schedule.startTime, schedule.stopTime02:00 to 07:00HH:MM, 24-hour, whatever the time format shown; chosen on the screen with hour and minute boxes (#350). No stop time, or 00:00, runs to midnight, and a stop before the start crosses midnight
schedule.daysevery day0 (Monday) to 6 (Sunday); at least one when the schedule is on

How the queue applies them is in ENGINE_CONTRACT.md.

Updating from 0.1.x (#351, option B, PO decision): a saved maxConcurrentDownloads of 3, the old default, becomes 2 once, through migration 8 (DATA_AND_MIGRATIONS.md). Apollo Download Manager can't tell a chosen 3 from the old default, since the queue section is saved whole. Every other value is kept, and a 3 chosen after the update stays.

Folders

FolderSettings in crates/velocity-core/src/destination.rs (#31), V1's downloads settings, saved as the settings document's downloads section. #30 puts them on the Settings screen (PO decision on #31). What they do is in FILE_NAMING.md.

SettingDefaultBounds
defaultDirectoryempty: the system's Downloads folder, or Downloads in the home folder when the system names noneAn absolute folder, at most 4096 bytes, with no control character and no .. part
autoCategorizeon—
categorySubfolderson, V1's default since its #38—
  • Before any are saved, the defaults apply.

  • Saved ones that can't be read, or that fail their checks, are a DATABASE error and are left as they were, never replaced by the defaults.

History

StorageSettings in crates/velocity-core/src/history.rs (#32), V1's storage settings, saved as the settings document's storage section. set_storage_settings saves them and applies them at once; the app also applies them when it starts. #30 puts them on the Settings screen.

SettingDefaultBounds
historyRetentionDays900 to 3650; 0 keeps entries forever
maxHistoryEntries10,000100 to 1,000,000
  • What they forget: entries no longer in the download list that finished more than the retention ago, then the oldest beyond the most kept. An entry still in the list is never forgotten.

  • Never files: forgetting an entry deletes its record, with its checkpoint and torrent row, and never a file on disk.

  • A failure to apply them at start is the snapshot's storageError, which the window shows; the app runs on.

The window

V1's general, notifications and appearance settings and its first-run flag, in crates/velocity-core/src/app_settings.rs (#29). Each is a section of the settings document, on the Settings screen (#30). What the window does with them is in UI_ARCHITECTURE.md.

SectionSettingDefaultBounds
generalcloseToTrayonClosing hides the window in the tray, when there is one
startMinimizedoffStarts hidden in the tray, when there is one, also when it starts at sign-in
startAtLoginoff; finishing the first-run setup turns it on in a released buildStarts the app when the user signs in (#321, PO decisions). On Windows, a value named after the app's identifier under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run; on Linux, <identifier>.desktop in the XDG autostart folder (velocity_core::autostart). Saving changes the entry first, and a refusal saves nothing. At each start the entry is put right when the app has moved. A development build never adds itself unless switched on, and V1's entry is never touched
confirmExitWithActiveonAsks before quitting while downloads are active
notificationsonCompleteonAlso when a torrent starts seeding, or waits for its files to be chosen
onFailureon—
onStartoffWhen a download leaves the queue or a pause, not when it recovers from a retry or a stall
onEngineFailureonWhen the transfer engine or the torrent helper becomes unavailable
appearancethemesystemsystem, light or dark
densitycompactcompact or comfortable, for the download list (#59)
timeFormattwentyFourHourtwentyFourHour or twelveHour, for every time the app shows (#350; PO decision)
layout.sidebarWidthnull: about 17% of the window, 220 to 240 px184 to 360 px
layout.sidebarCollapsed, layout.sidebarVisibleoff, on—
layout.detailsWidthnull: a fifth of the window, 300 to 340 px280 to 600 px, for the details panel (#61)
layout.detailsVisibleoff—
visibleColumnsname, size, progress, speed, eta, status, category, added (V1's)The download list's columns, in display order (#59). Always with name, each column once. The ids are V1's 13: those above and downloaded, avgSpeed, destination, started and completed (ColumnId, fixture columns.json)
columnWidthsnone: each column's default widthThe widths the user set by dragging, in CSS pixels by column id, 48 to 1200 px (#59)
onboardingcompletedoffSet by finishing the first-run setup, which also saves its folder as downloads.defaultDirectory
upkeepwindowDataClearedoffNot on any screen: set once the window's old browsing data, with the autofill entries earlier versions kept, was cleared (#345, PRIVACY.md)
  • Saved and read like the folder settings: a panel or column width outside its bounds, and a column list without name or with a column twice, are refused with INVALID_INPUT. An unknown column id doesn't parse, so set_appearance refuses it before it reaches the core, and a saved section that can't be read is a DATABASE error for the window, left as it was.

  • Read when the app starts: general and notifications are read when the app starts. A section that can't be read is left as it was, and its defaults apply until it is fixed, so closing and notifications keep working. The Settings screen (#30) changes them while the app runs, and closing and notifications follow at once.

What a build can do

Settings and details never offer what the build can't do. The engine reports its capabilities per protocol (ProtocolCapabilities, CONTRACTS.md): whether it downloads the protocol at all, and whether it segments, resumes, checks validators, uses HTTP/2 and can encrypt it. In the UI, availability (src/capabilities.ts) turns that into "available" or a reason, and CapabilityOption shows a control that is disabled, with the reason beside it, when the build lacks something; the Settings screen's Metalink switch is one, disabled only with an engine that can't read Metalink (#30).