Отладка состояния асинхронной гонки python с defaultdict - PullRequest
0 голосов
/ 29 сентября 2018

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

in_dict = defaultdict(list)
out_dict = defaultdict(list)
guard = asyncio.Lock()

async def collate(k, v):
    async with guard:
        in_dict[k].append(v)
    await asyncio.sleep(wait_time)
    async with guard:
        if k in in_dict and in_dict[k]:
            out_dict[k] = out_dict[k] + in_dict.pop(k)
        elif k in out_dict:
            handle_collated(out_dict.pop(k))

Однако, кажется, что где-то существует состояние гонки, где out_dict[k] все еще содержит элементы, которые были обработаны.

Спасибо

1 Ответ

0 голосов
/ 29 сентября 2018

...out_dict[k] still contains elements that have been processed. - Непонятно, какова цель вашего примера, поэтому решение будет невозможно.На первый взгляд это выглядит как логическая проблема.

Оставляя в стороне асинхронное:

>>> in_dict = collections.defaultdict(list)
>>> out_dict = collections.defaultdict(list)

Код всегда делает k:v элемент в in_dict первый

>>> k, v = 1, ''
>>> in_dict[k].append(v)

Такif k in in_dict and in_dict[k] всегда будет True, а набор elif никогда не будет выполнен.

>>> k in in_dict
True
>>> bool(in_dict[k])
True
>>>
>>> if k in in_dict and in_dict[k]:
...     out_dict[k] = out_dict[k] + in_dict.pop(k)
... elif k in out_dict:
...     print(f'elif executed: {out_dict.pop(k)}')

>>> in_dict
defaultdict(<class 'list'>, {})
>>> out_dict
defaultdict(<class 'list'>, {1: ['']})

Далее вызов

>>> k,v = 1,'q'
>>> in_dict[k].append(v)
>>>
>>> if k in in_dict and in_dict[k]:
...     out_dict[k] = out_dict[k] + in_dict.pop(k)
... elif k in out_dict:
...     print(f'elif executed: {out_dict.pop(k)}')
>>>
>>> in_dict
defaultdict(<class 'list'>, {})
>>> out_dict
defaultdict(<class 'list'>, {1: ['', 'q']})
>>>

Оператор if

...