длительных, неблокирующих операций.
Суть в том, что у меня есть однопоточное игровое ядро, очень похоже по своей сути на STA приложение вин форм. Это ядро обслуживает кучу клиентов, поэтому никогда не выполняет никаких длительных операций: т.е. у него есть входная очередь с событиями, которую оно разгребает и куча выходных очередей, в которые ядро кидает данные, которые нужно отправить игрокам.
А теперь задача: когда игрок подключается к серверу, нужно загрузить данные о нём с бд. Напрямую грузить нельзя, поэтому я сделал так, что запускается асинхронная операция загрузки, которая кидает в очередь сообщений данные о загруженном игроке. Вроде норм.
Но меня смущают некие маловероятные сценарии, типа: игрок подключился, отключился и вот наконец пришли данные о нём из базы. Или: игрок подключился, отключился, подключился и вот пришли данные о нём раз, и данные два, да ещё и порядок не детерминирован.
Для того чтобы не думать о таких сценариях, я решил что стоит сделать отмену асинхронной операции. Т.е. я говорю стороджу загрузить данные, стородж возвращает ид операции, если игрок отключился, то удаляем ид операции. Получается, что когда данные таки загрузятся из базы, можно понять нужны эти данные ещё или нет.
Отменять саму асинхронную операцию не вариант, т.к. она уже может завершиться, а данные уже попасть во входную очередь.
Проблема в том, что реализация пока получается не огонь :( а мне кажется, что проблема типовая для гуёвых программистов: типа грузим картинки в фоне, а если пользователь что-то нажал, то картинку уже не нужно грузить.
Что думаете? Может существует более простой способ, чем тот что я описал? Или есть готовые, удобные реализации, которые можно стырить?
обычно просто используют отмену (cancellation токены), т.е. данные ты загрузил, но они не нужны уже (в токене была выставлена отмена) и дальше просто ничего не должно произойти
Мне кажется, ты правильно делаешь. Как минимум, в самом конце операции (когда ты уже завершил работу и находишься синхронно в ядре) нужно проверять, что игрок всё ещё подключен к серверу. Если не подключен — игнорировать результаты операции. Отменять in-flight операцию через cancellation token необязательно. Насколько я понимаю, ситуация это редкая, и ты рискуешь нагородить много кода ради копеечной экономии.
Обсуждают сегодня