Jestem nowością Usługi internetowe Pythona Flask. Próbuję opracować resztę usług internetowych, która będzie miała wspólną kolejkę, wiele wątków stale piszą do tej kolejki po stronie serwera i wreszcie, gdy użytkownik wywołuje metody uzyskania, usługa powinna zwrócić pierwszy element w kolejce współdzielonej.

Próbowałem rozpocząć opracowanie tego, najpierw wdrażając zmienną udostępnioną, następującą jest kod, którego używałem,

from flask import Flask
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    count = count+1
    return {'count':count}

if __name__ == "__main__":

    app.run() 

Ale nawet powyżej kodu nie działa. Następnie pomyślałem o użyciu pamięci podręcznej dla wspólnej zmiennej, ale nie będzie to właściwy sposób na wdrożenie wspólnej kolejki (mojego ostatecznego celu). Proszę dać mi swoje porady

7
Proceso 24 listopad 2013, 09:40

2 odpowiedzi

Najlepsza odpowiedź

Rzecz, którą chcesz zrobić, jest trochę bardziej złożony, boję się.

Kolba (i inne systemy WSGI Python) nie działają w jednym wątku - zwykle muszą odrodzić wiele wątków i instancji, aby poradzić sobie z żądaniami przychodzącymi bez blokowania lub bez wielu żądań dostęp do tego samego "pierwszego zadania" na tym samym czas. W ten sposób zmienne globalne nie działają, ponieważ mogą one w innych prostych skryptach Python jednokątnych.

Potrzebujesz drogi do różnych procesów do wszystkich dostępu do tej samej pojedynczej kolejki danych.

Zwykle oznacza to outsourcing kolejkę danych do zewnętrznej bazy danych. Jedną popularną opcją jest Redis. Jest dobra intro do kolby i redisa dokładnie to:

http://flask.pocoo.org/snippets/73/

Mam nadzieję, że to pomoże ci we właściwym kierunku!

6
Daniel Fairhead 24 listopad 2013, 17:10

W twoim przykładzie masz kilka robaków. Oto wersja, która działa:

from flask import Flask, jsonify
app = Flask(__name__)

count= 0 #Shared Variable

@app.route("/")
def counter():
    global count
    count = count+1
    return jsonify({'count':count})

if __name__ == "__main__":
    app.run()

Dwa problemy, które masz w swojej wersji, to:

  • Tęskniłeś za zadeklarowaniem count jako globalny w funkcji widoku. Bez globalnej deklaracji funkcja widoku tworzy zmienną lokalną o tej samej nazwie.
  • Odpowiedź zwrócona przez funkcję widoku nie może być słownikiem, musi być obiektem lub Response. Poprawiłem to za pomocą jsonify(), aby przekonwertować dict do sznurka JSON.

Należy pamiętać jednak, że ten sposób tworzenia wspólnej wartości nie jest solidna. W szczególności zauważ, że jeśli uruchomisz tę aplikację pod serwerem internetowym, który tworzy wiele procesów, każdy proces będzie miał własną kopię wartości count.

Jeśli chcesz to zrobić na serwerze produkcyjnym Moje zaleceniem jest użycie bazy danych do przechowywania wartości udostępnionej.

1
Miguel 24 listopad 2013, 20:00