gallery_server_client_s190js/docs/activity_scan.md
2026-10-26 11:00:14 +01:00

341 lines
8.3 KiB
Markdown

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.
1. 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.
2. 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
3. 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.
4. 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.
5. 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
6. 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.