Skip to main content

DB Persister

Il servizio DB Persister è responsabile della persistenza delle posizioni GPS validate nel database PostgreSQL.

Panoramica

Flusso di Elaborazione

1. Ricezione Messaggi

Il servizio consuma messaggi dal Redis Stream positions:validated:

{
"position": "{\"latitude\": 41.90, \"longitude\": 12.50, ...}",
"uniqueId": "019175767229"
}

2. Lookup Device

Per ogni messaggio, il servizio cerca il device nel database:

device_id = self.device_cache.get_device_id(unique_id)

La ricerca avviene nella tabella devices:

SELECT * FROM devices WHERE unique_id = '019175767229'

[!IMPORTANT] Il unique_id deve corrispondere esattamente a quello inviato dal dispositivo, inclusi eventuali zeri iniziali.

3. Cache dei Device

Il DeviceCache mantiene una cache in memoria per evitare query ripetute:

class DeviceCache:
def get_device_id(self, unique_id: str) -> Optional[int]:
# Prima controlla la cache in memoria
if unique_id in self._cache:
return self._cache[unique_id]

# Se non in cache, cerca nel DB
device = session.query(Device).filter(
Device.unique_id == unique_id
).first()

if device:
self._cache[unique_id] = device.id
return device.id

return None

4. Persistenza Position

Se il device viene trovato:

  1. Crea oggetto Position con tutti i campi dal JSON
  2. Inserisce nella tabella positions
  3. Aggiorna devices con position_id e last_update
-- Inserisce la nuova position
INSERT INTO positions (device_id, latitude, longitude, ...) VALUES (...);

-- Aggiorna il device con l'ultima position
UPDATE devices
SET position_id = :new_position_id,
last_update = NOW()
WHERE id = :device_id;

Tabelle Database

Tabella devices

CampoTipoDescrizione
idINTEGERID numerico interno
unique_idVARCHARID univoco del dispositivo (IMEI, serial, etc.)
nameVARCHARNome assegnato dall'utente
position_idINTEGERFK all'ultima position
last_updateTIMESTAMPUltimo aggiornamento

Tabella positions

CampoTipoDescrizione
idSERIALPrimary key
device_idINTEGERFK al device
latitudeDOUBLELatitudine
longitudeDOUBLELongitudine
altitudeDOUBLEAltitudine
speedDOUBLEVelocità in knots
courseDOUBLEDirezione in gradi
validBOOLEANPosition valida
device_timeTIMESTAMPOra del dispositivo
server_timeTIMESTAMPOra del server
attributesJSONBAttributi aggiuntivi

Troubleshooting

Device Not Found

Se nei log appare:

WARNING - Device not found for uniqueId: 019175767229

Verificare che il unique_id nel database corrisponda esattamente:

-- Controllare il valore attuale
SELECT unique_id FROM devices WHERE name = 'PET';

-- Correggere se necessario (es. aggiungere zero iniziale)
UPDATE devices SET unique_id = '019175767229' WHERE unique_id = '19175767229';
UPDATE device_list SET device_unique_id = '019175767229' WHERE device_unique_id = '19175767229';

Position Rejected

Se le position non arrivano al DB Persister, controllare il servizio position-filter:

  • reason=invalid → Il GPS non ha un fix valido
  • reason=zero → Coordinate 0,0
  • reason=future → Timestamp nel futuro
  • reason=past → Timestamp troppo vecchio

Metriche Prometheus

MetricaTipoDescrizione
db_persister_positions_totalCounterPosition persistite
db_persister_positions_failed_totalCounterPosition fallite
db_persister_processing_secondsHistogramTempo di elaborazione
db_persister_batch_sizeHistogramDimensione batch

Configurazione

Variabili ambiente in config.py:

VariabileDefaultDescrizione
REDIS_URLredis://redis:6379URL Redis
DATABASE_URL-URL PostgreSQL
INPUT_STREAMpositions:validatedStream di input
CONSUMER_GROUPdb-persister-groupNome consumer group
BATCH_SIZE100Dimensione batch
HEALTH_PORT8080Porta metriche