remote job plugin - degoya/rDownloader GitHub Wiki
A remote job is work that happens at somebody else's provider and outlives the call that started it. A magnet handed to a debrid account answers with an identifier, not a file: it runs for minutes or hours, it may stop half-way until a person has said which files they want, and the account keeps it afterwards. This is the type to write for a debrid or cloud-download provider; the files it finishes are then fetched like any other download.
Seven short calls carry a job, and none of them waits; two more answer whether the provider's cache already holds a source.
| Scaffold | rdownloader plugin new --type remote-job |
plugin_type |
remote-job |
| World | remote-job-plugin |
| Exports |
claims, identify, submit, adopt, poll, choose, discard, cache-kinds, check-cached
|
| Template | sdk/templates/remote-job |
| Contract | Interface remote-job |
- Nothing here waits. Every call returns on the provider's next answer. The waiting lives on a row in the host's database, which costs no fuel and survives a restart.
-
You remember nothing. A guest is instantiated fresh for every call; whatever the next one
needs goes into
remote-handle.job-state, which the host stores verbatim and hands back. -
The duplicate is prevented on the host's side.
identifygives the host a content key derived locally, the host writes it down beforesubmitis called, andadoptcloses the one window that leaves — a crash between the request leaving and the identifier coming back. -
You never see a credential. The account's token reaches a request only as
{{secret:<reference>}}, towards the domains the manifest declares.
The scaffold asks for secrets — the one vault slot the account's token lives in — and net_http
with the provider's API. A remote-job manifest without at least one net_http domain is refused:
a job that cannot reach its provider cannot submit, poll, choose or delete. job-context is
granted by the type.
[extension] claims names the provider slug whose account the jobs run on; the host looks the
account up and expands the secret for it.
[extension] containers names the files the provider takes as a container — any of torrent,
nzb, dlc, rsdf — and is left out for a provider that takes no file. rDownloader reads it
without running the plugin to decide which accounts the LinkGrabber offers an NZB import to; your
identify still decides when a file actually arrives, so the two should agree. Only a remote-job
manifest may declare it, and an unknown or repeated format is refused at install.
Ask for exactly what you use: the install preview shows every grant, and a component importing an interface its manifest does not grant cannot be instantiated. Every capability is listed under Capabilities.
-
identifynever makes a request and never invents a key. A key that changed between two calls, or that needed a request, would defeat the guard it exists for. - An unknown state waits rather than failing a job that is going well.
-
Only a provider that keeps the answer may ask. After
choose, the next poll has to read the selection back from the provider; a job that asks a second time is ended. -
discardis called from one explicit, confirmed request and from nowhere else. What rDownloader did not put in somebody's account on its own it does not take out on its own.
The scaffold's cache-kinds returns an empty list, and then check-cached is never called. A
provider whose cache can be asked answers exactly one answer per query, in the order given, and
reads only — see The cache question.
plugin new reads its templates from sdk/templates, so run it from a checkout of the repository:
git clone https://github.com/degoya/rDownloader.git
cd rDownloader
rdownloader plugin new --type remote-job --out ../myjobs
cd ../myjobsWithout an installation of rDownloader, the packaging tool rd-pack —
cargo build --profile release-test -p rd-pack in the checkout — takes the same arguments:
target/release-test/rd-pack plugin new --type remote-job --out ../myjobs.
The directory name becomes the crate name and the plugin's slug (--name sets another). The
scaffold gets its own plugin id, its own copy of the contract in wit/rdownloader.wit and its own
Ed25519 key pair: plugin-signing.key, whose public half is already in manifest.toml. Keep that
file out of version control.
-
src/source.rsderives the content key of a magnet or a.torrentlocally;src/digest.rswrites SHA-1 out, so the only dependency stayswit-bindgen. -
src/reply.rsmaps your provider's state vocabulary. -
src/guest.rsholds the calls against your provider's API. -
manifest.toml:secrets,[capabilities.net_http] domains,[extension] claims. -
locales/en.json: the English text of every failure code you report.
Change description and author under [metadata], and read the comment at the top of
src/lib.rs: it states what the host promises this type.
cargo testThe unit tests need no WebAssembly toolchain: only src/guest.rs is wasm32-specific. Give every
answer of your provider you read a test of its own.
cargo build --release --target wasm32-unknown-unknown
wasm-tools component new target/wasm32-unknown-unknown/release/myjobs.wasm -o target/myjobs.wasmThis needs the wasm32-unknown-unknown target and wasm-tools 1.261.0, the version the bundled
plugins are made with: cargo build makes a core module that carries the world src/guest.rs
generates, and wasm-tools component new turns it into the component. The plugin is built
without WASI: a component importing anything outside rdownloader:plugin is refused — see
Building without WASI.
rdownloader plugin package --manifest manifest.toml \
--component target/myjobs.wasm \
--locales locales --key plugin-signing.key --output myjobs.rdplug
rdownloader plugin conformance myjobs.rdplug --jsonconformance answers whether this application would run the package; it has to be clean before
you publish. For a key that outlives the scaffold, rdownloader plugin keygen --role plugin --output ./keys writes a pair: the Base64 in the .pub file goes into public_key, and key_id
gets a name of your own. In CI, RDOWNLOADER_PLUGIN_SIGNING_KEY holding the private key's PEM
text replaces --key. Details:
Packaging, signing and distribution.
For a first try without signing, package with --development instead of --key and start
rdownloader serve --plugin-development-mode, the only mode that accepts an unsigned package.
Install a signed package under Settings → Plugins → Add as an upload, or with
rdownloader plugin install myjobs.rdplug --root data/plugins. Review before installing shows
every permission and the signing key; a key this installation has not seen asks to be trusted —
compare its fingerprint. The message after installing says whether the plugin runs at once or
after the next restart; see Installing and trust.
Add an account for your provider under Settings → Accounts, then use Hand a magnet to an account under Remote jobs: the job shows there with its progress.
Publish the .rdplug together with your key's fingerprint, or — so that people get your new
versions in the Catalogue — in a plugin repository of your own: a signed index built with
rdownloader plugin index build and a repository-role key. A repository only delivers: every
package in it still needs your plugin key, approved by the person installing it. See
A repository index and
Running a plugin repository.
The SDK's reusable CI workflow,
sdk/ci/plugin.yml, builds,
checks the imports, packages and runs conformance on every push and pull request; it signs only
on a push to the default branch or a tag, so a pull request never sees the key.
- Remote jobs in the plugin reference — what the host does with each call, in full
-
Interface
remote-job— every function and type, generated from the contract - Developing a plugin — the tools, translations, errors and what every type shares
-
The
remote-jobtemplate on GitHub