8.3 KiB
Certo. Dopo le modifiche in s179js, il flusso Activity è ormai molto simile a quello Photo, ma la notifica alla gallery segue ancora il percorso tramite POST /activities.
- Flusso attuale di scansione Activity
Quando premi Scan Activities:
UTENTE
│
▼
Scan Activities
│
▼
routes/scanActivities.js
│
▼
scanActivitiesUser()
│
trova cartelle Activity
│
▼
scanActivity()
│
▼
scanActivityCartella()
│
trova FIT/GPX/TCX
│
▼
enqueueActivityIngestJob()
│
▼
activity_ingest_jobs
│
┌─────────────┼──────────────┐
│ │ │
pending processing done
│
▼
│ ACTIVITY DAEMON [A]
└────────────►│
▼
runOneJob()
│
▼
scanActivitySingle()
│
▼
processActivityFile()
│
parsing FIT/GPX/TCX
│
▼
activities DB
│
├───────────────┐
│ │
▼ ▼
geocode_jobs ritorno meta
│
▼
GEOCODE DAEMON [G]
│
▼
geocoding
Lo Scan adesso è solo il produttore
Questa è la differenza fondamentale rispetto a prima.
Prima:
Scan ↓ trova file ↓ parsa FIT ↓ salva Activity ↓ file successivo
Adesso:
Scan ↓ trova file ↓ mette job pending ↓ file successivo
Per questo nel log vedi velocemente:
[S] 📥 [ACTIVITY QUEUE] xxx.fit status=pending inserted [S] 📥 [ACTIVITY QUEUE] yyy.fit status=pending inserted [S] 📥 [ACTIVITY QUEUE] zzz.fit status=pending inserted
e poi:
[S] Scan ATTIVITÀ COMPLETATO
Questo però non significa che tutte le Activity siano elaborate. Significa solamente che la fase di discovery ha finito di riempire la coda.
- Il daemon svuota la coda
Parallelamente [A] fa:
activity_ingest_jobs │ ▼ prende primo pending │ ▼ processing │ ▼ parse FIT │ ▼ salva Activity │ ▼ accoda Geocode │ ▼ sincronizza server │ ▼ done │ ▼ prende IMMEDIATAMENTE il pending successivo
Infatti nel tuo log:
[A] Avvio job ... [A] Nuova activity ... [A] Activity ... inviata al server remoto [A] Job ... completato; stato: done [A] Avvio job successivo ...
Non ci sono 2 secondi tra un'attività e l'altra.
I 2 secondi servono solo quando:
pending = 0
- Geocode è completamente indipendente
Quando scanActivitySingle() salva l'Activity esegue anche:
enqueueGeocodeJob
quindi:
ACTIVITY DAEMON │ ▼ activities DB │ └────────────► geocode_jobs │ ▼ GEOCODE DAEMON [G] │ ▼ geocoding
Activity daemon non aspetta che il Geocode finisca.
Per questo nel log puoi vedere:
[A] job Activity successivo
mentre:
[G] geocodeWorker processing
sta ancora lavorando sull'attività precedente.
- Flusso attuale di notifica alla gallery Activity
Qui il percorso è leggermente diverso da Photo.
Quando scanActivitySingle() restituisce la nuova Activity:
ACTIVITY DAEMON [A]
│
▼
scannedActivity/meta
│
▼
postWithAuth()
│
▼
POST BASE_URL/activities
│
▼
routes/activities.js
│
▼
INSERT activity
ON CONFLICT MERGE
│
▼
invalidateActivitySpatialIndex()
│
▼
broadcastToUser()
│
payload:
type: "added"
id: activityId
entity: "activity"
│
▼
WebSocket
│
▼
CLIENT
│
▼
Activity Gallery
Quindi la notifica alla gallery non viene inviata direttamente dall'Activity daemon.
Il daemon fa:
Activity daemon ↓ HTTP POST ↓ server ↓ WebSocket ↓ Gallery
Questo è importante perché il processo [A] non importa ws-server e quindi non rischia di aprire un secondo WebSocket sulla porta 4002.
- Pipeline completa
Mettendo insieme tutto:
SCAN
│
▼
trova FIT/GPX/TCX
│
▼
activity_ingest_jobs
│
│ pending
▼
ACTIVITY DAEMON [A]
│
▼
parse FIT/GPX/TCX
│
▼
activities DB
│
┌────────────┴─────────────┐
│ │
▼ ▼
geocode_jobs activity meta
│ │
▼ ▼
GEOCODE DAEMON [G] POST /activities
│
▼
SERVER
│
INSERT / UPDATE
│
▼
WebSocket
│
▼
ACTIVITY GALLERY
Activity daemon
│
▼
job status = done
│
▼
prossimo pending
- Cosa significa per il futuro banner
Ora abbiamo finalmente una coda affidabile:
activity_ingest_jobs
quindi il banner Activity non deve più basarsi sul vecchio:
scan_status.json
Può mostrare direttamente:
remaining = pending + processing
Per esempio:
Activities processing: 27
poi:
Activities processing: 26 Activities processing: 25 ... Activities processing: 1
e quando:
pending = 0 processing = 0
il banner scompare.
Questo sarebbe molto più corretto del vecchio progress dello Scan, perché lo Scan può aver finito di accodare i file mentre l'Activity daemon ha ancora 30 FIT da elaborare.