o7412369815963
он передает новые запросы в старые потоки
Ключевое слово - одновременно - подразумевается что в одном потоке (процессе?) одновременно работает одно приложение, формально wsgi приложение должно работать и при multithread, и при multiprocess, и run_once. Т.е. нигде не сказано (run_once не гарантируется) как оно будет запущено, и будет ли поток переиспользован или нет - это вопрос реализации сервера - который нас не должен интересовать.
Вообще, на мой взгляд, если есть возможность не использовать thread local - лучше этого и не делать.
Формально у нас есть request (который мы создаем при начале запроса) - и его должно быть вполне достаточно для всего что зависит от отдельного запроса, также его, по моему, лучше передавать в контроллер в явном виде. Всякие параллельные запросы к данным и прочее, должно решать хранилище (база данных), а не как ни контроллер.
Прелесть же wsgi именно в абстракции от всякого рода реализаций, сокетов и прочего.
Архитектурно thread local решает, как правило, следующие вопросы:
1. Доступ к текущему контексту выполнения (request, конфигурация и т.д.) - решается передачей реквеста в контроллер, с конфигурацией можно поступить также (вообще environment самое то ей место, либо пусть там будет ссылка на то где ее взять), проблема возникает только в том случае, когда нам нужна конфигурация в модели, но туда можно ее и передать)
2. Совершение шаблонных действий при начале/завершении запроса. Например для соединения с базой данных, обработки самого реквеста, либо, например, добавления в контекст шаблонизатора чего-нибудь. Можно либо добавить в request соответствующие декораторы (типа flask-овского @app.before_request), для себя завел пару интерфейсов, вроде этого
class IRequestListener(Interface):
'''Request listener
'''
def before_request(context, request):
"""Call before request"""
def after_request(context, response):
"""Call after request"""
class ITemplateRenderListener(Interface):
'''Template render notifications
'''
def template_rendered(template, context):
"""Called when template rendered"""
def update_template_context(context):
"""Update the template context with some
commonly used variables."""
3. Может для чего-то еще.
PS. Также можно написать всякого рода middleware (там где это действительно нужно) типа сессий, csrf и т.д.
По мне, так tread local действительно используется только для “быстрого вхождения” в продукт. Сами авторы как-то обходятся. И, действительно, некоторые решения, лично мне, даются чуть более тяжело, но это, по моему, дело привычки.