Un problema di Performance (con soluzione!)

Un problema di Performance (con soluzione!)

C’è un detto che gira tra coloro che lavorano con il codice e che programmano: “Per quanto riguarda l’ottimizzazione di codice, non fare mai ottimizzazione di codice!” di questo stesso detto ne esiste una versione seguente che recita “Per quanto riguarda l’ottimizzazione di codice, non fare ottimizzazione di codice ORA”. L’idea alla base di questi detti è quella di non sprecare tempo e fatica nel fare ottimizzazione di codice quando, molto probabilmente, non hai ancora individuato se ne hai bisogno e se quello che stai ottimizzando è davvero cruciale. 

Per quanto riguarda l’ottimizzazione di codice, non fare mai ottimizzazione di codice

Un tipico esempio è minificare i file javascript e css, zippare il codice html di una pagina per ridurne la dimensione, ma poi arriva qualcuno e ci mette un immagine da 80 Mega non ottimizzata. Quindi anche se hai risparmiato 5Kb di file, l’immagina da 80Mega fondamentalmente distrugge tutto.

Alla radio dove ho una trasmissione (e sono anche responsabile tecnico) hanno un sito www.radiocittaperta.it e non mi sono mai trovato nella situazione di dover ottimizzare qualcosa: l’hosting dedicato e le soluzioni di cache del CMS non hanno mai mostrato colli di bottiglia del caso. 

Tuttavia c’è una funzionalità che ha dato del filo da torcere: il sito aggiorna in tempo reale il titolo della canzone in onda, l’immagine associata  e il programma in onda. Queste informazioni sono sparse su più fonti diverse: il titolo viene dal fornitore di streaming, il programma in onda è conservato sul database, l’immagine viene salvata sull’hosting del sito prendendola dalle API di Spotify. Per far si che le informazioni siano aggiornate costantemente quello che fa il sito (ma anche l’app) è chiamare un endpoint ogni 3 secondi. Immagino esistano anche modi più moderni e ottimizzati per fare questa cosa, ma il caro vecchio polling funziona da sempre. 

Il problema di chiamare un API ogni 3 secondi non è tanto nella chiamata, ma nel fatto che tale chiamata porta con se tutto il contesto, compreso il database e, per ogni chiamata, viene fatta una query per sapere che programma stia andando in onda. Non è micidiale, ma se siamo in parecchi sul sito e tutti sono fermi ad ascoltare e vedere la pagina, questo significa che per ogni utente, ogni 3 secondi, viene tirata su una connessione e viene fatta una query. E sta cosa non va benissimo, rallenta il sito e (a volte) lo rende inaccessibile con un errore del tipo “MOD_FCGID: CAN’T APPLY PROCESS SLOT PHP

Come si risolve questo problema ?

Ovviamente esistono numerose soluzioni: si potrebbe pensare di usare un database veloce, per esempio un noSql, oppure creare una tabella ottimizzata sul database MySql, ma ho preferito usare le conoscenze che ho acquisito durante una conferenza in Germania. Lì infatti, ho ascoltato un talk in cui si diceva che, nonostante una sfiducia generalizzata, spesso l’utilizzo di file di testo è la soluzione migliore e anche la più veloce. Questo perché hard disk e modi di accesso alle informazioni mantenute come file, possono essere anche molto, molto veloci.

Per questo ho impostato la creazione di un file di cache locale, con le informazioni salvate come testo:


{
title: "KATZENJAMMER con MIRO BARSA",
thumb: "https://www.radiocittaperta.it/wp-content/uploads/2020/09/KATZENJAMMER-IMAGE.png",
show_podcastfilter: "katzenjammer",
url: "https://www.radiocittaperta.it/shows/katzenjammer-con-miro-barsa/",
day: 4,
start: "10:00",
end: "12:00",
category: "0",
song: "Pink Floyd - Whish you were here",
cover: "https://www.radiocittaperta.it/wp-content/uploads/2020/09/wish-you-were-here.png"
}

Come gestisci l’aggiornamento titolo o programma in onda?

Per il titolo la cosa è piuttosto semplice: quando lo speaker aggiorna il titolo, allora viene aggiornato anche il file di cache sul sito. Questo perché il titolo della canzone in onda non arriva da un posto magico, ma è inserito a mano dallo speaker di turno, ad ogni cambio canzone. 

Per il programma in onda invece ho usato cron di wordpress, che ogni 15 minuti fa la query e aggiorna il file con i dati reali. 15 minuti è un tempo ragionevole e poi, di base, l’idea è che le trasmissioni cambino all’ora o’clock, o (al massimo) al 30esimo minuto. Quindi ogni 15 minuti è più che sufficiente.

Come leggi le informazioni?

Questo è facilissimo, con una chiamata ajax direttamente dal sito (o con una chiamata dall’app) viene richiesto il file statico, per esempio in questo modo:


var proxyURL = "https://www.radiocittaperta.it/mystaticfile.json";
jQuery.ajax({
     type: "GET",
     cache: false,
     url: proxyURL,
     async: true,
     dataType: "json",
  success: function(data) {
      applyTitle(data)
  },
  error: function(e) {}
})

Non entro nel merito della funzione applyTitle di base si preoccupa di aggiornare titolo, immagine e trasmissione in onda.

MiroAdmin