341 lines
8.3 KiB
Markdown
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.
|