Italian community of Lazarus and Free Pascal

Programmazione => Lazarus e il web => Topic aperto da: xinyiman - Maggio 19, 2021, 12:53:41 pm

Titolo: Webserver e pascal script - problema
Inserito da: xinyiman - Maggio 19, 2021, 12:53:41 pm
Ciao a tutti. Ho un problema con un mio programmino. Praticamente un web server che interpreta del codice pascal attraverso pascal script.
L'esempio è banale, ma quando uso in maniera massiccia il programma la memoria occupata sale e non viene liberata fino alla chiusura del programma.
Testato con ubuntu e mac os. Il problema è replicato su entrambi.
Per replicare il problema scaricate il file allegato e decomprimetelo.
Poi compilate il progetto

laz_https_server_test_ps/pkg/laz_http_server.lpi

Successivamente compilate la console per stressare il programma

laz_https_server_test_ps/console/pkg/console.lpi (richiede le indy installate)

Entrambi gli eseguibili vengono creati in

laz_https_server_test_ps/bin/

Ora lanciate entrambi i programmi (laz_http_server da terminale), aprite il monitor delle attività e identificate la riga di laz_http_server e monitorate la memoria occupata.
Poi spostatevi sulla console che avete compilato e premete l'unico checkbox che trovate e in successione il pulsante che trovate in altro a sinistra.

Praticamente la console si occuperà di interrogare ciclicamente il programma laz_http_server. Quando volete bloccarlo basta che togliete il flag al componente checkbox.








Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 19, 2021, 09:59:34 pm
Ciao.

Allego il file console.lpi modificato per la compatibilità con le versioni "stable" di Lazarus.

I progetti venogno compilati ed eseguiti sotto Windows. Provo ad analizzare quanto hai descritto.

Saluti
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 19, 2021, 10:16:14 pm
Eseguendo quanto sopra io in Windows ottengo un:

"HTTP/1.1 500 Internal Server Error"

da parte del programma console, e la memoria del server web aumenta.

Saluti
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 19, 2021, 11:01:11 pm
Sembra, anzi è certo, che il web server "cerchi" alcune risorse che non trova, ed in effetti file RES o LRS non esistono ne vengono creati neanche ricompilando.

Mancano queste risorse:
 TCustomHTTPModule
 TSessionHTTPModule
 TCustomFPWebModule
 TFPWebModule

Questo è probabilmente la causa dell'aumento di memoria.

Saluti
Titolo: Re:Webserver e pascal script - problema
Inserito da: xinyiman - Maggio 19, 2021, 11:13:23 pm
Sembra, anzi è certo, che il web server "cerchi" alcune risorse che non trova, ed in effetti file RES o LRS non esistono ne vengono creati neanche ricompilando.

Mancano queste risorse:
 TCustomHTTPModule
 TSessionHTTPModule
 TCustomFPWebModule
 TFPWebModule

Questo è probabilmente la causa dell'aumento di memoria.

Saluti
Se hai risolto cortesemente potresti l'esempio corretto?! Grazie mille
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 20, 2021, 12:13:45 am
No, no ... non ho risolto.

Ho solo visto che il web server cerca di caricare quelle "resource" e non le trova, generando la risposta "500".

Il webserver gira e non crasha, ma risponde sempre con la "Server Internal Error" e ad ogni richiesta del client aumenta la memoria occupata.

Molto probabilmente il mancato caricamento delle risorse manda in "crash" il trhread relativo (che dovrebbe essere creato ad ogni richiesta del client ???) e la memoria non viene liberata.

Occorre approfondire ... probabilmente manca qualcosa nell'uso di fpweb. Domani se riesco provo a dare una occhiata.

'Notte
Titolo: Re:Webserver e pascal script - problema
Inserito da: xinyiman - Maggio 20, 2021, 07:12:12 am
Ma se così fosse dovrebbe occupare memoria anche se commenti la parte di Pascal script. Invece il problema si verifica per via del psscript1.compile ma non capisco il perché.
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 20, 2021, 07:42:51 pm
Ciao e scusa per l'attesa nella risposta.

Allora ho dovuto un pò trafficare perchè in Windows, quando l'applicazione è a linea di comando non sono disponibili le risorse (vedi post precedenti) e deve essere fatto tutto a mano. C'è una nota di fpc che conferma questo (stralcio).
Citazione
Pure Hand Coding (No Form Designer Required)

It's not a must to use Lazarus' form designer to write an fpWeb application. You can use pure hand coding technique to write it. The secret lies in the 3rd parameter of RegisterHTTPModule : SkipStreaming. When this parameter is set to true, fpWeb will not search for .lfm resource. Therefore everything must be manually handled: property settings, event handlers, action registration, etc.


Quello che hai descritto effettivamente accade esattamente anche in Windows e accade con una frequenza e con un valore di incremento di memoria che è variabile e quindi sono convinto che non è un lag ma il normale funzionamento dell'applicativo come web server,

Di fatto usando una utility VMMAP che mappa tutta la memoria dell'applicativo, consentendo anche di forzare il rilascio della classica memoria di "paginazione" che viene bloccata dal sistema operativo con tecnologie o a tempo o per quantità (il tutto bilanciato dal carico del PC), si rileva che l'applicativo ritorna sempre alla quantità di memoria originale quando si rilascia la memoria.

Ho fatto diverse prove, usando semafori per evitare la chiamata sovrapposta anche in caso di uso del pool di thread, e devo dire che di fatto "leak" non c'è (anche se i dati visualizzati direbbero l'incontrario).

Tra poco aggiungerò un post con gli screen shoot ..... 
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 20, 2021, 09:59:56 pm
1) Immagine iniziale con la memoria usata dall'app;
2) Immagine con app in esecuzione, memoria usata;
3) Immagine dopo l'azzeramento del workset;

Si vede che la memoria in uso è tornata ai valori iniziali.

Saluti
Titolo: Re:Webserver e pascal script - problema
Inserito da: nomorelogic - Maggio 21, 2021, 01:01:32 pm
avete fatto la prova attivando heaptrc sulle opzioni del compilatore?
lanciando a riga di comando, quando il programma termina ti fa vedere se ci sono effettivamente dei leak
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 21, 2021, 03:02:56 pm
Si, nessun problema riscontrato. D'altronde in linea generale (anche se l'analisi è un pò più complessa) quando resetti il "workset" e la memoria ritorna al livello iniziale (fatto salve eventuali allocazioni permanenti durante l'uso) non ci dovrebbero essere sorprese.

Occorre approfondire l'uso specifico sia di fpweb che di psscript, in particolare sull'uso dei thread: ossia  i "datamodule", i "callback" o gli "eventi" sono threadsafe o si devono serializzare gli accessi alle risorse comuni, come ad esempio la variabile mynumber usata in quest'esempio ?

In allegato due report: 1 blocco con 10 cicli, 2 blocco con 100 cicli.

Ciao
Titolo: Re:Webserver e pascal script - problema
Inserito da: nomorelogic - Maggio 22, 2021, 10:07:58 am
Ciao
ci ho lavorato un po' anche io ma non ne sono venuto a capo...

Ho trovato questo link che dice che alcuni errori sono normali all'interno del debugger.
https://lists.lazarus-ide.org/pipermail/lazarus/2011-August/196238.html (https://lists.lazarus-ide.org/pipermail/lazarus/2011-August/196238.html)
Ricevo comunque l'internal server error e non so da cosa dipende. :(

Cmq proverei a rifare il tutto senza il TFPWebModule ma scrivendo tutto il codice a manina.
Di sicuro si evitano i problemi con le risorse che in un http server non servono.
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 22, 2021, 12:17:17 pm
Ciao
ci ho lavorato un po' anche io ma non ne sono venuto a capo...

Ho trovato questo link che dice che alcuni errori sono normali all'interno del debugger.
https://lists.lazarus-ide.org/pipermail/lazarus/2011-August/196238.html (https://lists.lazarus-ide.org/pipermail/lazarus/2011-August/196238.html)
Ricevo comunque l'internal server error e non so da cosa dipende. :(

Cmq proverei a rifare il tutto senza il TFPWebModule ma scrivendo tutto il codice a manina.
Di sicuro si evitano i problemi con le risorse che in un http server non servono.

Allego il progetto "a mano", ancora più semplificato rispetto al progetto di @xinyiman. CIò che è stato riportato corrisponde, ma non è un problema. La memoria in uso verrà liberata quando al sistema operativo serve (almeno così dovrebbe essere).

Saluti
Titolo: Re:Webserver e pascal script - problema
Inserito da: nomorelogic - Maggio 22, 2021, 01:14:20 pm
ho fatto dei test: così non ci sono più gli internal error e la memoria non aumenta durante la vita del server :)

rimane solo un blocco non liberato, bisogna capire cos'è ma mi sembra che vada molto meglio
Titolo: Re:Webserver e pascal script - problema
Inserito da: xinyiman - Maggio 24, 2021, 04:53:09 pm
Ho provato il codice di DragoRosso, ho constatato quanto segue

Se eseguo il codice così com'è la memoria usata non aumenta nel tempo.
Se vado a togliere la compilazione con  heaptrc la memoria occupata cresce nel tempo.

Sia su linux che su mac. Arrivati a questo punto mi basta compilare usando questa modalità. Però è una cosa curiosa.
Titolo: Re:Webserver e pascal script - problema
Inserito da: DragoRosso - Maggio 24, 2021, 07:16:23 pm
Come accennavo, il problema della memoria che "cresce" dipende da diversi fattori. Non è detto che la memoria che cresce indichi un effettivo consumo di memoria. Anzi in quasi tutti i programmi l'uso della memoria indicata dai vari tool di diagnostica non corrisponde a ciò che è in realtà.
La liberazione di memoria, ossia il fatto che in un programma si vede diminuire la memoria usata nel tempo invece che crescere o essere stabile è legata alle prestazioni della "macchina" sia in hardware (processore, cache, hard disk, etc ...) sia da come è stato configurato il sistema operativo.

In genere, tutti i sistemi operativi mantengono la cache della memoria, ossia il GC (garbage collector) evita di chiedere troppo spesso ai programmi di liberare memoria se non c'è necessità.

Quando usiamo un "malloc" o simili (ossia migliaia di volte nel programma a ns. insaputa) l'allocazione e la deallocazione viene generalmente effettuata mantenendo la vecchia memoria liberata come cache (non è proprio una cache ma gli si avvicina molto) e allocando nuova memoria, da qui la crescita continua.

Uno dei modi per non fare crescere la memoria in uso è allocare il massimo di risorse alla partenza del programma e poi usare queste anche solo in parte.

I driver in genere non soffrono di questa problematica perchè la gestione della memoria avviene ad un livello più basso.

Cosa "scateni" il meccanismo di liberazione fisica o viceversa il mancato rilascio apparente della memoria non è proprio così chiaro e nonostante più di qualcuno abbia cercato di fare luce su questo in realtà più si scava e meno luce si vede.

Usando immagini (tante immagini raw !!, in alcune applicazioni sino a 24 GByte) potete immaginare (scusate il gioco di parole  ;D ) quante volte mi sia trovate di fronte a questi falsi problemi. E l'unica soluzione che ho trovato è quella di allocare tutto all'inizio. Da li poi non si deve spostare neanche di un BIT.

@xinyiman Curioso è un eufemismo, non sai che fastidio mi dà questa cosa. Quando accade si perdono ore se non giorni per verificare che tutto sia a posto  :'(  :'(

Saluti