Поток Werkzeug BaseWSGIServer зависает после обработки запроса. Терминал не отвечаетPython

Программы на Python
Ответить
Anonymous
 Поток Werkzeug BaseWSGIServer зависает после обработки запроса. Терминал не отвечает

Сообщение Anonymous »

Это помешало мне сделать что-нибудь полезное более недели. Если у вас есть опыт работы с Python/Werkzeug/Flask/многопоточностью, пожалуйста, помогите...
Теперь, обычно вы запускаете приложение Flask в отдельном терминале через py flask.py, при этом его нужно вручную развернуть и выключить с помощью Ctrl-C. Моему приложению Python этот локальный сервер нужен только в определенных случаях, например: для получения токена с помощью потока кода авторизации Spotify, чтобы я мог позже делать действительные запросы с помощью их веб-API.
Мой < Файл em>auth_server.py — это «раздел», отвечающий за все это. Здесь находится класс с именем LocalServerThread, который является подклассом Thread, взятым дословно из этого ответа. 8 лет назад это был единственный полезный ответ для Windows в море дерьма; увы, к сожалению, на сегодняшний день это лишь частично работающий пример.
Вот он во всей красе:

Код: Выделить всё

from werkzeug.serving import make_server

class ServerThread(threading.Thread):
THREAD_NAME = 'LocalServerThread'

def __init__(self, app):
threading.Thread.__init__(self, name=LocalServerThread.THREAD_NAME)
self.server = make_server('127.0.0.1', 8080, app)
self.ctx = app.app_context()
self.ctx.push()

def run(self):
log.info('starting server')
self.server.serve_forever()

def shutdown(self):
self.server.shutdown()

def start_server():
global server
app = flask.Flask('myapp')
# App routes defined here
server = ServerThread(app)
server.start()
log.info('server started')

def stop_server():
global server
server.shutdown()
Вот остальная часть рассматриваемого кода в моем auth_server.py :

Код: Выделить всё

def start_local_http_server():
app = Flask(__name__)

@app.route('/')
def home():

@app.route('/login')
def login():

@app.route('/callback')
def callback():

global server
server = LocalServerThread(app)
server.start()
print(fr'Started {LocalServerThread.THREAD_NAME}, serving: http://127.0.0.1:8080')

def stop_local_http_server():
server.shutdown()
Вот мой реальный код из main.py, который использует этот код:

Код: Выделить всё

if not auth_server.validate_token(reject=True):
auth_server.start_local_http_server()

time.sleep(4)

auth_server.stop_local_http_server()

print('Finally Done')
И вот тут все разваливается...

Я запускаю его с помощью py ./main.py. Если я просто позволю ему работать, выключение будет работать идеально, отключая все правильно. Хорошо.

Однако если, пока основной поток спит в течение этих 4 секунд, я перейду к любому из маршрутов ('/', '/login', '/callback'), а сервер успешно обслуживает мне страницу, затем, когда программа достигает self.server.shutdown(), она просто зависает там где-то 90-300 секунд, прежде чем, наконец, выйдет и достигнет печати('Finally Done') вернемся к главному нить. В это время терминал будет выглядеть так, не позволяя программе завершить работу:
Изображение

Это просто бесит. Я тоже не могу понять, что, черт возьми, происходит во время отладки. self.server.shutdown() углубляется в метод socketserver.py BaseServer Shutdown(), и я не могу войти в него что-то дальше, чем две строки внутри, как будто оно чего-то ждет... Но я принес вам стек вызовов:
Это стеки вызовов рядом, прямо перед отладчик теряет представление о том, что происходит.

Первое: стандартный забег. ________________________ Второе: переход к '/' во время 4-секундного сна:


Изображение

Изображение

Примечание. Еще раз: я использую Windows.

Есть ли кто-нибудь, кто смотрит на это и обладает знаниями/опытом, чтобы увидеть проблему? Это действительно помогло бы не только мне, но и нашим потомкам, я подозреваю...

Подробнее здесь: https://stackoverflow.com/questions/793 ... unresponsi
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»