Безопасен ли поток промежуточного программного обеспечения Django?

#python #django #thread-safety #middleware

#python #django #потокобезопасность #промежуточное программное обеспечение

Вопрос:

Безопасны ли потоки промежуточного программного обеспечения Django? Могу ли я сделать что-то вроде этого,

 class ThreadsafeTestMiddleware(object):

    def process_request(self, request):
        self.thread_safe_variable = some_dynamic_value_from_request

    def process_response(self, request, response):
        # will self.thread_safe_variable always equal to some_dynamic_value_from_request?
  

Ответ №1:

Почему бы не привязать вашу переменную к объекту запроса, вот так:

 class ThreadsafeTestMiddleware(object):

    def process_request(self, request):
        request.thread_safe_variable = some_dynamic_value_from_request

    def process_response(self, request, response):
        #... do something with request.thread_safe_variable here ...
  

Комментарии:

1. Еще лучше было бы привязать его к request.session ( docs.djangoproject.com/en/1.3/topics/http/sessions ).

Ответ №2:

Нет, определенно нет. Я пишу об этой проблеме здесь — в результате сохранение состояния в классе промежуточного программного обеспечения является очень плохой идеей.

Как указывает Стив, решение состоит в том, чтобы вместо этого добавить его в запрос.

Комментарии:

1. Эта ссылка разорвана. Вот правильный вариант: blog.roseman.org.uk/2010/02/01 /…

Ответ №3:

Если вы используете mod_wsgi в режиме демона с несколькими потоками, ни один из этих параметров не будет работать.

WSGIDaemonProcess domain.com пользователь = www-группа данных = www-потоки данных = 2

Это сложно, потому что это будет работать с сервером разработки django (одиночный локальный поток) и давать непредсказуемые результаты в рабочей среде в зависимости от времени жизни вашего потока.

Ни установка атрибута запроса, ни манипулирование сеансом не являются потокобезопасными в mod_wsgi. Поскольку process_response принимает запрос в качестве аргумента, вы должны выполнить всю свою логику в этой функции.

 class ThreadsafeTestMiddleware(object):

    def process_response(self, request, response):
        thread_safe_variable = request.some_dynamic_value_from_request
  

Комментарии:

1. Это неверно. Ваш объект запроса / ответа не является общим для потоков и / или запросов, поэтому он безопасен в использовании.

2. У меня не сработало. У меня были случаи, когда данные запроса первого пользователя устанавливались на время существования потока и вызывали проблемы.

3. Объект request создается в начале запроса и не удаляется до тех пор, пока запрос не пройдет через все классы промежуточного программного обеспечения, не будет обработан и снова передан обратно через промежуточные программы. Это не имеет ничего общего с обработкой потоков — это один и тот же объект, не разделяемый на протяжении всего процесса.

4. Имеет полный смысл, но это было сломано и всегда сохраняло данные первого пользователя. pastebin.com/zJ5wct3Z

5. Здесь неверно ваше использование self.refcode = refcode . Измените его на request.refcode = refcode , затем прочитайте его обратно из request.refcode в process_response методе. Я надеюсь, что это поможет.