Особенности работы bubbleteaОбещал поделиться техническими особенностями, которые вызвали у меня проблемы. Делюсь.
много событий, случайный порядокПорядок завершения асинхронных операций может быть случайным, поэтому важно синхронизировать доступ к storage`/`state. Я встречался с этой проблемой в тестах toggle-значения завершенности задачи (и не только, это один из примеров).
В bubbletea Update обрабатывает сообщения последовательно, но tea.Cmd запускаются асинхронно. Несколько команд могут завершиться не в том порядке, в котором их создали, поэтому обработчики их сообщений должны переживать переупорядочивания.
Должен быть мем, но я просто опишу его.•
Drake hates: установить значение counter = n.
- Так у нас победит последнее примененное сообщение, а не обязательно последнее действие пользователя.
•
Drake likes: изменить значение counter + k.
- Так у нас может измениться порядок применения, но результат останется тем же.
Но! И тут тоже надо очень осторожно подходить, потому что возможно конкурентное чтение текущего состояния для diff и применение обновления.
Короче,
многопоточка (tm).
Что мы делали?
- сначала перестали мутировать состояние до *DoneMsg.
- ранее мы сначала изменяли state, потом ходили в store, а потом уже отправляли сообщение, на которое мог кто-то реагировать;
- теперь мы сначала ходим в store, а потом отправляем *DoneMsg, в обработчике которого обновляется state.
- а затем добавили nonce к сообщениям thinglist. nonce здесь - это идентификатор конкретного времени жизни: сообщения от старого экземпляра модели пропускаются.
Коммиты:
•
2efd2c0•
79eb212.
Вывод простой: сообщения и его обработчики должны быть безопасны к переупорядочиванию или явно защищены от устаревших результатов, иначе
многопоточка (tm).
тест закончился, фоновые операции нетЗдесь проблема была уже не в порядке применения, а в жизненном цикле приложения. В bubbletea тест мог уже дойти до tm.Quit(), но это еще не значило, что все ранее запущенные tea.Cmd действительно закончили работу, no-no-no. Было бы слишком просто.
В моем случае такие операции пытались делать свои грязные делишки после завершения приложения и удаления директории.
В cosas это в итоге починилось коммитом
6f46daf: в storage добавили Close(), который запрещает новые операции (будет отдаваться ошибочка) и ждет завершения уже идущих записей.
Все просто...Или нет?