Здесь определенно есть проблема:
for sid in app["sockets"]: # you are iterating over a list here
await sio.save_session(...) # your coroutine will yield here
Вы просматриваете список app["sockets"]
, и в каждой итерации вы используете ключевое слово await
.Когда используется ключевое слово await
, ваша сопрограмма приостанавливается, и событие зацикливается, чтобы проверить, может ли быть выполнена или возобновлена другая сопрограмма.
Допустим, что сопрограмма connect(...)
запущена, пока session_route
ожидает.
app["sockets"].append(sid) # this changed the structure of the list
connect(...)
изменил структуру списка.Это может сделать недействительными все итераторы, которые в данный момент существуют для этого списка.То же самое относится к сопрограмме disconnect(...)
.
Так что либо не изменяйте список, либо, по крайней мере, не используйте итератор повторно после изменения списка.Последнее решение легче достичь здесь:
for sid in list(app["sockets"]):
await sio.save_session(...)
Теперь цикл for перебирает копию исходного списка.Изменение списка теперь не будет «мешать» копии.
Обратите внимание, однако, что добавления и удаления из списка не распознаются копией.
Итак, короче говоря, ответ на вашвопрос да , но это не имеет ничего общего с async io.Та же проблема может легко возникнуть в синхронном коде:
for i in my_list:
my_list.remove(1) # don't do this