Как справиться с состоянием гонки на Django -канале потребителя? - PullRequest
1 голос
/ 16 марта 2020

Я внедряю сервис с django -каналом, я сделал несколько объяснений по поводу своих проблем, но вы можете просто прокрутить вниз до нижней части, где я задаю свои вопросы, и игнорировать их.

В этом Сервис Я использую систему кэширования asyn c для повышения производительности сервиса. Запись в этот кеш поднимает проблемы состояния гонки. Вот две основные функции этого кеша

async def get_room_data_dict(self):
      data = await self.cache_client.get(self.key)
      return data

async def set_room_data_dict(self, room_data_dict):
      is_success = await self.cache_client.set(self.key, room_data_dict)
      return is_success

Теперь вот проблема с этим методом.

### coroutine 1 ###
room_data_dict = await cache_manager.get_room_data_dict()
# In the line below a context switch occurs and coroutine 2 continues to do some tasks
new_room_data_dict = await do_somthing(room_data_dict)
# coroutine 1 continue but room_data_dict is the old one and coroutine 1 going to save it so what coroutine 2 did is actually not applied
await cache_manager.set_room_data_dict(new_room_data_dict)

### coroutine 2 ###
# this coroutine continues without a context switch
room_data_dict = await cache_manager.get_room_data_dict()
new_room_data_dict = await do_somthing(room_data_dict)
await cache_manager.set_room_data_dict(new_room_data_dict)
# gets back to coroutine 1 and continues its code

Теперь, если вы присмотрелись и получили некоторое образование по ОС, вы увидите, что изменение coroutine 2 на room_data_dict на самом деле не применяется.

Вот что я бы сделал, чтобы предотвратить эту проблему, я бы изменил функции, как показано ниже

async def get_room_data_dict(self):
      await self.room_data_dict_semaphore.acquire()
      data = await self.cache_client.get(self.key)
      return data

async def set_room_data_dict(self, room_data_dict):
      is_success = await self.cache_client.set(self.key, room_data_dict)
      self.room_data_dict_semaphore.release()
      return is_success

Этот метод решит моя проблема, если и только если семафор в коде является общим для группового канала.

Итак, вот что я спрашиваю, и если вы можете ответить на любой из этих вопросов, я могу решить мою проблему:

  1. Как я могу поделиться экземпляром объекта между двумя сопрограммами (в моей проблеме между двумя групповыми каналами)?
  2. В python, когда вы делаете an_instance.str (), вы получаете что-то, что показывает, что это адрес памяти экземпляра ... Могу ли я получить этот конкретный c экземпляр с этим адресом?
  3. Любые другие решения моей проблемы, кроме моей (с использованием семафоров), будут очень приветствуется.

1 Ответ

0 голосов
/ 30 марта 2020

Как насчет получения / снятия блокировки во внешней области видимости (сопрограмма 1).

В любом случае, различные системы блокировки позволяют идентифицировать замок с помощью строкового ключа, так что его можно получить / снять с разных прицелы. Вы даже можете использовать распределенную блокировку, например python -redis-lock.

...