WebDownloadStore

The owner of every folder web.fetch downloads into (opal-web-reference §OWRD-12).

Inherits QObject

In the namespace opal::web. Declared in src/libs/libopalweb/opalweb/WebDownloadStore.hpp.

Detailed description

Why the registry does not own them

AttachmentRegistry owns no file: "a dropped folder stays exactly where the user has it, and is never modified or removed". Every other caller relies on that. A download has no such owner, so this store is one, and the registry keeps its contract.

Layout

<cache>/opal-web/run-<pid>-<id>.lock               held while this process runs
<cache>/opal-web/run-<pid>-<id>/<fetch>/<host>/    the grant: source.txt, ...

<cache> is app::PathResolver::cacheDir(). <fetch> is unique per call, and the grant points at the <host> folder inside it, so the attachment card names the host the page came from.

The run folder exists because two processes can share one cache: two hubs, or a test beside the application. A grant lives in ONE process, so no process can tell from its own grants whether another process still needs a folder. The run folder's lock can: a sweep removes another run's folder only when its owner no longer holds the lock. The lock sits beside the folder and is taken before the folder is made, so no sweep ever sees a run folder without its lock.

When a folder goes

  • When the user takes the page back. The × on the attachment card calls AttachmentRegistry::remove, and this store hears grantRemoved. A conversation switch clears every grant with clear(), which emits no grantRemoved, so the page stays for a return to that conversation.
  • When the application quits, through removeAdopted().
  • At startup, through sweepOrphans(): every run folder whose process has ended, and every fetch folder of this run that no grant points into. Grants live only as long as the process, so after a crash every folder of that run is an orphan. Without the sweep every crash leaks a folder, and nothing ever says so.

⚠ A conversation opened from history names its fetches by attachment id. The bytes of a fetch do not outlive the process that fetched them, so the restored grant is missing and the model is told; it can fetch again. The cache is the place for bytes that can be fetched again.

Thread-safe: web.fetch runs on a plan thread, and the registry signals from whichever thread changed it.

In this section