Re: [Python] threading, local() and uwsgi: how protected is local()? - RITENTO
On 13/12/17 09:12, Alessandro Dentella wrote: ... > Avendo sollecitato Roberto De Ioris anche in privato, mi ha in effetti > risposto: > > Ciao, di solito si usano i thread local per avere dati > NON-condivisi tra i thread. Se e' il tuo caso, allora puoi usarli > senza problemi a patto che abiliti il GIL in uWSGI con > --enable-threads. > > Va da sè che se non abilito --enable-threads, problema non ne ho, > visto che non uso threads... e --threads imploca --enable-threads. Esatto. Questa era anche la mia sensazione. >> In realta' e' l'altro risultato che mi lascia dei dubbi, quando >> threading.local non e' usato. > > Qui ti ho perso... quale sarebbe "l'altro risultato"? Lancia i test che ho mandato, una volta con la variabile d'ambiente thread_safe=1 e la seconda senza. Quando il test non usa threading.local, il risultato mi lascia perplesso. Il test lancia 400 richieste, mi aspetto che il totale sia x <= 400 e invece e' costantemente > 400. ___ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python
Re: [Python] threading, local() and uwsgi: how protected is local()? - RITENTO
Ciao Marco, grazie per la risposta e l'attenzione. > > 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. Avendo sollecitato Roberto De Ioris anche in privato, mi ha in effetti risposto: Ciao, di solito si usano i thread local per avere dati NON-condivisi tra i thread. Se e' il tuo caso, allora puoi usarli senza problemi a patto che abiliti il GIL in uWSGI con --enable-threads. Va da sè che se non abilito --enable-threads, problema non ne ho, visto che non uso threads... e --threads imploca --enable-threads. > In realta' e' l'altro risultato che mi lascia dei dubbi, quando > threading.local non e' usato. Qui ti ho perso... quale sarebbe "l'altro risultato"? sandro *:-) ___ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python
Re: [Python] threading, local() and uwsgi: how protected is local()? - RITENTO
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 from itertools import groupby from operator import itemgetter import threading import urllib.request lock = threading.Lock() results = [] def get(url): for i in range(200): with urllib.request.urlopen(url) as response: content = response.read(300).decode('ascii') tid, c = map(int, content.split()) with lock: results.append((tid, c)) if __name__ == '__main__': t1 = threading.Thread(target=get, args=('http://localhost:9000', )) t2 = threading.Thread(target=get, args=('http://localhost:9000', )) t1.start() t2.start() t1.join() t2.join() results = sorted(results, reverse=True) tot = 0 for group, iterable in groupby(results, itemgetter(0)): last = next(iterable) tot += last[1] print('Thread: {0}, c: {1}'.format(*last)) print('Total:', tot) # thread_safe=1 uwsgi_python3 --http-socket :9000 --module test_local --threads 3 import os import random from threading import local, get_ident import time if not os.environ.get('thread_safe', False): class local: pass l = local() def application(env, start_response): l.__dict__.setdefault('c', 0) c = l.c time.sleep(0.01 + (random.random() / 50 - 0.01)) c += 1 l.c = c response = b'%d %d' % (get_ident(), c) headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ] start_response('200 Ok', headers) return [response] ___ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python
[Python] threading, local() and uwsgi: how protected is local()? - RITENTO
*** 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 [1] https://stackoverflow.com/questions/3227180/why-is-using-thread-locals-in-django-bad [2] https://www.pythonanywhere.com/forums/topic/710/ ___ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python
[Python] threading, local() and uwsgi: how protected is local()?
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 [1] https://stackoverflow.com/questions/3227180/why-is-using-thread-locals-in-django-bad [2] https://www.pythonanywhere.com/forums/topic/710/ ___ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python