Repository navigation
fix(follow): never list a follower whose master was refused - #4086
Merged
Merged
Conversation
Нашлась причина зависания из #4083. CharData::set_master молча отказывает, если цепочка лидеров замкнулась бы в кольцо: void CharData::set_master(CharData::ptr_t master) { if (follow::MakesLoop(this, master)) { follow::ReportLoopError(this, master); return; } m_master = master; } а AddFollowerSilently результат не смотрел и клал ведомого в список лидера в любом случае. Получался последователь без хозяина: StopFollower такого снять не может, он сразу выходит с "stop_follower(...) without master", и DieFollower, разгоняя свиту, крутится на нём вечно. По боевому логу всё сходится. 19:22:12 -- "попытка сделать цикл в цепочке последователей", текущий лидер Морхеля костяная гончая, пробуют подчинить гончую Морхелю. Указатель не взялся, а в свиту Морхеля гончая легла. 19:25:42 -- Морхель встаёт на постой, ExtractCharFromWorld зовёт DieFollower, и сервер уходит в вечный цикл на этой гончей. AddFollowerSilently теперь возвращает, подчинился ли ведомый, и в список кладёт только когда хозяин действительно взялся. AddFollower на отказе молчит -- раньше он печатал "Вы начали следовать за ...", даже когда подчинение не состоялось. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Причина зависания из #4083. Дополняет #4084: там страховка в цикле, здесь — то, откуда берётся само рассогласование.
Как получается последователь без хозяина
CharData::set_masterмолча отказывает, если цепочка лидеров замкнулась бы в кольцо:А
AddFollowerSilentlyрезультат не смотрела:Получается ведомый, который числится в свите, но хозяином лидера не считает. Снять его нельзя:
StopFollowerна таком сразу выходит сstop_follower(...) without master, не тронув список. АDieFollower, разгоняя свиту черезwhile (!ch->followers.empty()), крутится на нём вечно.Как это легло в боевой лог
Морхель следовал за костяной гончей; попытка подчинить гончую Морхелю замкнула бы кольцо,
set_masterотказал — и гончая всё равно оказалась в свите Морхеля без хозяина. Через три минуты Морхель встал на постой,ExtractCharFromWorldпозвалDieFollower, и сервер ушёл в вечный цикл. Адрес0x5aed82c254d0из этой строки — тот жеch, что в трейсеgen_receptionistиз issue.Правка
AddFollowerSilentlyвозвращает, подчинился ли ведомый, и кладёт его в список только когда хозяин действительно взялся. Проверяется результат, а не условие: так страховка держит и любой будущий отказ внутриset_master, а не только текущую проверку на кольцо.Заодно
AddFollowerна отказе молчит — раньше он печатал «Вы начали следовать за ...», даже когда подчинение не состоялось.Проверка
Сборка
-Dbuild_profile=release -Dbuild_tests=trueбез предупреждений,./tests/tests— 796 passed, 3 skipped (те же, что и до правки).🤖 Generated with Claude Code