Se controlliamo i documenti per l'applicazione flask globale, flask.g
, dice:
Per condividere dati validi per una richiesta solo da una funzione all'altra, una variabile globale non è sufficiente perché si interromperebbe negli ambienti con thread. Flask ti fornisce un oggetto speciale ciò garantisce che sia valido solo per la richiesta attiva e questo restituirà valori diversi per ogni richiesta.
Ciò si ottiene utilizzando un proxy thread-local (in flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
L'altra cosa che dovremmo tenere a mente è che Python sta eseguendo il primo passaggio del nostro decoratore durante la fase di "compilazione", al di fuori di qualsiasi richiesta, o flask
applicazione. Ciò significa key
all'argomento viene assegnato un valore di 'shop_{}_style'.format(g.city.id)
all'avvio della tua applicazione (quando la tua classe viene analizzata/decorata), al di fuori di flask
contesto della richiesta.
Ma possiamo facilmente ritardare l'accesso a flask.g
utilizzando un proxy pigro, che recupera il valore solo quando viene utilizzato, tramite la funzione di callback. Usiamo quello già in bundle con flask
, il werkzeug.local.LocalProxy
:
from werkzeug.local import LocalProxy
class ShopAreaAndStyleListAPI(Resource):
@redis_hash_shop_style(key=LocalProxy(lambda: 'shop_{}_style'.format(g.city.id)))
def get(self):
# if not found from redis, query from mysql
pass
In generale (per non flask
o non werkzeug
app), possiamo usare un simile LazyProxy
da ProxyTypes
pacchetto.
Non correlato a questo, vorrai anche correggere il tuo redis_hash_shop_style
decoratore non solo per recuperare da redis
, ma anche per aggiornare (o creare) il valore se stantio (o non esistente), chiamando il wrapping f()
quando appropriato.