staticmethod с веб-сервисом django — неожиданное поведение. Должен быть создан только 1 экземпляр (одноэлементный)

#django #multithreading #python-multiprocessing

#django #многопоточность #python-многопроцессорный

Вопрос:

@staticmethod в django не работает. статический метод должен выполняться только один. Однако для тестирования я сделал 3 параллельных вызова, и статический метод вызывался 3 раза. Ниже приведен код и выходные данные:

Код:

 class KafkaReceiver:
    _kafka_consumer = None
    def __init__(self, topic):
        KafkaReceiver._kafka_consumer = self.create_only_one_consumer()

    @staticmethod
    def create_only_one_consumer():
        if KafkaReceiver._kafka_consumer is None:
            KafkaReceiver._kafka_consumer = KafkaConsumer(KafkaReceiver._topic)
            print("Consumer Created......")
        return KafkaReceiver._kafka_consumer
 

Вывод:

 Consumer Created......
Consumer Created......
Consumer Created......
 

Код параллельного вызова:

 r1 = grequests.get('http://localhost:5014/message/?message=hello', callback=do_something)#, hooks = {'response' : do_something})
r2 = grequests.get('http://localhost:5014/message/?message=helloworld', callback=do_something)#, hooks = {'response' : do_something})
r3 = grequests.get('http://localhost:5014/message/?message=hellothere', callback=do_something)#, hooks = {'response' : do_something})

grequests.map([r1, r2, r3])
 

Что ожидается:
Для каждого вызова веб-сервиса django django создает (я думаю) новый поток. Однако класс здесь не должен создавать экземпляр consumer . Это проблема с блокировкой (я пробовал lock и RLock, он не работает с django)

Вторая странная вещь заключается в том, что при дальнейших вызовах django этот статический метод не выполняется.

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

1. Возможно, что всем трем запросам удастся пройти через оператор if до того, как будет установлен потребитель. Какую блокировку вы пробовали — a threading.Lock или a multiprocessing.Lock ? Ваш сервер приложений может использовать рабочие процессы, а не потоки.

2. многопоточность. блокировка и RLock вообще не работали… С многопроцессорной обработкой. блокировка выдает ошибку: семафор или блокировка, выпущенная слишком много раз

3. Я подозреваю, что это где-то связано с процессами / потоками, создаваемыми django при каждом вызове веб-сервиса

4. Можете ли вы показать, как вы использовали multiprocessing.Lock существующий код?

5. « @staticmethod определяет create_only_one_consumer(): KafkaReceiver . _lock.acquire() # с помощью KafkaReceiver . _lock: попробуйте: если KafkaReceiver._kafka_consumer нет: KafkaReceiver._kafka_consumer = KafkaConsumer(KafkaReceiver._topic print(«Потребитель создан ……») наконец: KafkaReceiver. _lock.release() возвращает KafkaReceiver._kafka_consumer «