[Python] threading, local() and uwsgi: how protected is local()? - RITENTO

Marco Giusti marco.giusti a posteo.de
Mer 13 Dic 2017 09:00:37 CET


On 07/12/17 18:39, Alessandro Dentella wrote:
> ***********
> Rimando nella speranza che qualcuno legga e desideri e magari stia
> cercando di combattere la noia...
> ***********
>
> Ciao,
>
> [disclaimer: si parla di Django ma il tema mi pare più generale poi si
> parla di uwsgi e mi pare che Roberto qui legga...]
>
> al lavoro abbiamo avuto una interessante discussione su un modo di
> tenere in Django una informazione sempre disponibile (request / user e
> recentemente un 'dominio').
>
> Una soluzione a volte considerata "da evitare" ma che ci è sempre
> andata bene è stata fatta seguendo un vecchio snippet di Django [2 -
inizio]
> che immagazzina i dati in threading local().
>
> Quello che mi ha fatto balzare sulla sedia ieri è che un collega mi ha
> mostrato un post [1] su StackOverflow dove si dice che uwsgi non
> garantisce che quello che si mette in local() non sia condiviso fra
> thread differenti... nonostante la documentazione Python dica:
>
>    Thread-local data are data whose values are thread specific
>
>
> In una pagina citata in questo post [2] si espone una situazione molto
> simile alla mia, ma non vedo una risposta soddisfacente sul fatto che
> sia in effetti vero
>
>   * che uwsgi forza un uso condiviso della ram fra thread differenti e
>   * se esiste un modo per bypassarlo
>
> io ho spesso in uwsgi.ini (ma ho anche occasionalmente di più):
>
>   threads: 1
>   processors: 2
>
> È questo che mi ha salvato fino ad oggi?
>
>
> sandro
> *:-)
>
>
> PS: tecnicamente io scrivo nel _thread_local tramite middleware ad
>     ogni request, non esiste possibilità che resti il vecchio nella
>     nuova request


Ciao Alessandro,

incuriosito dalla tua domanda e partaggiando il tuo stesso stupore ho
fatto qualche ricerca.

Prima di tutto vorrei iniziare dicendo che faccio piu' confidenza al
gruppo di unbit piuttosto che al commento di qualcuno in un sito. Mi
sembrava di aver letto nella documentazione di uWSGI che l'obiettivo
principale di uWSGI sia la correttezza, le performance vengono dopo.
Ovviamente non ritrovo la frase in questione ma che cambino la semantica
di threading.local per ragioni di performance mi sembra un suicidio. Se
fai un veloce grep nel codice di Django ti accorgerai che Django stesso
usa local() internamente.

Per scrupolo ho fatto una piccola ricerca nei sorgenti di uWSGI e non
trovo conferma di una simile castroneria.

Sono gia' bloccato, non so' piu' come continuare. Sono stati portati
esempi concreti a supporto della tesi? No.

Allego due file di test e come puoi verificare e threading.local
funziona esattamente come ci si aspetterebbe. In realta' e' l'altro
risultato che mi lascia dei dubbi, quando threading.local non e' usato.


Marco
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        client.py
Tipo:        text/x-python
Dimensione:  879 bytes
Descrizione: non disponibile
URL:         <http://lists.python.it/pipermail/python/attachments/20171213/22c8c63a/attachment.py>
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        test_local.py
Tipo:        text/x-python
Dimensione:  622 bytes
Descrizione: non disponibile
URL:         <http://lists.python.it/pipermail/python/attachments/20171213/22c8c63a/attachment-0001.py>


Maggiori informazioni sulla lista Python