Quando usarlo
Il prodotto svolge un lavoro che può durare secondi o ore: leggere un albero di
cartelle, importare file, comunicare con un dispositivo. I passi usano come
esempio un job acme.import in un crate crates/acme-import;
examples/rescuewerk mostra lo stesso schema con la scansione di una
cartella.
Regole da rispettare
- Il codice di prodotto vive in crate di prodotto che dipendono da
app-api; i crate del template (crates/app-*) non dipendono mai da un prodotto. - Un comando non aspetta mai un job.
start_jobrestituisce subito l'id e la UI segue gli eventi;wait_for_jobserve solo alla CLI e ai test. - L'handler chiama
ctx.checkpoint()?almeno una volta per unità di lavoro: pausa e annullamento hanno effetto solo lì. - Errori e avvisi sono codici
RW_*stabili, tradotti nelle tre lingue. Non mettere mai frasi o percorsi dell'utente in un codice. - Un percorso scelto nella UI passa da
validatePathprima di diventare un parametro del job.
Passi
- Crea
crates/acme-import/con unCargo.tomlcomeexamples/rescuewerk/crates/rescuewerk-scan/Cargo.toml(campi del workspace,app-apieserde_json,app-configper i test). Il workspace include giàcrates/*. Tieni i crate di prodotto sottocrates/: il test del catalogo inpackages/i18n/src/catalog.test.tscontrolla i codiciRW_*trovati incrates/eapps/, non inexamples/. - Implementa
JobHandlercome inrescuewerk-scan/src/lib.rsedocs/job-engine.md: leggi e controllactx.params(), fallendo conJobError::failed("RW_IMPORT_...")per un input non valido; chiamactx.checkpoint()?nel ciclo; segnalactx.progress(done, total)(Nonefinché il totale non è noto, il valore finale alla fine); usactx.warnper gli elementi che si possono saltare. Esporta il tipo come costante, per esempiopub const IMPORT_JOB_KIND: &str = "acme.import";. - Testa il job in
crates/acme-import/tests/tramiteAppApi, come farescuewerk-scan/tests/scan.rs: costruisci l'API conin_memory()e.job_handler(IMPORT_JOB_KIND, Arc::new(ImportJob)), avvia il job, attendi conwait_for_jobe verifica lo stato finale,done/totale l'error_codeper un input non valido. Usa file infixtures/, mai percorsi della macchina dello sviluppatore. - Registra l'handler nella shell: aggiungi
acme-import = { path = "crates/acme-import" }in[workspace.dependencies]diCargo.tomleacme-import.workspace = trueinapps/desktop/src-tauri/Cargo.toml, poi chiama.job_handler(...)sul builder inapps/desktop/src-tauri/src/main.rs. Fai lo stesso inapps/clise la CLI deve eseguirlo, e fai commit delCargo.lockaggiornato (la CI eseguecargo fetch --locked). Non serve un nuovo comando Tauri:start_job,pause_job,resume_jobecancel_jobesistono già. - Nella UI costruisci la richiesta in un service della feature, come
sampleJobRequestinapps/desktop/src/features/jobs/services/job-requests.ts: valida e limita i parametri e risolvi prima i percorsi convalidatePath. Avvialo constartJobe seguilo tramite le query dei job, che gli eventi già aggiornano. - Insegna il nuovo tipo a
MockNativeClientinpackages/native-client/src/mock.ts(rifiuta i tipi sconosciuti conRW_JOB_KIND_UNKNOWN), cosìpnpm deve i test dei componenti funzionano senza Rust. - Aggiungi ogni nuovo codice
RW_*inpackages/i18n/locales/*/errors.jsonin de-DE, en e it-IT, e i testi della UI incommon.json.
Completato quando
- i comandi di verifica superano;
- il job si può mettere in pausa, riprendere e annullare mentre gira, e
arriva a
COMPLETEDoFAILEDcon un codice tradotto; - il test di integrazione passa da
AppApisenza rete né percorsi della macchina; - ogni nuovo codice esiste nelle tre lingue.
