Repository navigation
fix(graph): resolve metadata paths across batch boundaries (BA-067) - #419
Merged
Merged
Conversation
…ilt project (github#226, github#227) A failed resident build was terminal for the life of the daemon: every later call answered internal_error until the broker's idle TTL, and a build that never finished held Loading forever. The resident now leaves Failed on its own pacing (base 5 s doubling to a 60 s cap, env-tunable), the previous cause stays visible while the retry runs, the build has a deadline that publishes a Failed instead of waiting forever, and the outcome of an attempt the deadline has retired can no longer overwrite whatever the live attempt published — the retry also re-reads the token before it touches the hub cursor. The reading tools answer a still-failed resident with one structured snapshot (state/reason/generation/attempts/retry_after_ms/failed_age_ms) in both the not-ready envelope and the RPC error's data, and the envelope's status reflects the state again. The wire change moves the contract to 3.5. A workspace built from source-set flags was covered only indirectly: the nested-configuration fixture now pins that SharedState::workspace builds the project through project::at, so reverting to Project::new fails the test. Tests: the retry schedule and its clamps, the deadline (unit and sweeper), the retired-attempt discards (success and failure, plus a retire-before-start), the single-snapshot failure answer, the envelope's closed readiness vocabulary, the cursor carried across a failed retry, and the boot composition gate.
… snapshot failure reason - run_load checks the attempt token and re-subscribes the hub cursor under one hold of `inner`, so a deadline retiring the attempt in between can no longer let the retired attempt replace the live attempt's subscription. - retry_delay doubles step by step up to the configured cap instead of clamping the exponent at 20, which plateaued below a long BSL_MCP_DIAG_RETRY_CAP_SECS. - failure_answer takes the reason from the same lifecycle snapshot as attempts and retry_after_ms; the error text of the five resident handlers uses it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server numbers its own requests (window/workDoneProgress/create) from 1, so a hover response awaited by bare id could match a server request with the same id. The legacy-extension-scope test now waits through Lsp::request, which requires a response shape, and a harness test pins that a same-id server request is skipped. wait_for_within dropped a message that arrived just past its deadline; it now returns it to the pending queue for the next wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wait_for_within checked its deadline before reading the queue, so a wait whose bound had already run out answered silence over a message that had arrived, and one taken in just past the bound was set aside unjudged, which wait_for_judging then reported as a silent server. The bound is now checked after each message: unrelated traffic still cannot stretch a wait, and a zero remainder polls once instead of seeing nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wait_for_judging checked its total ceiling before the predicate, so a matching message delivered in time but taken in just past the ceiling, as a late wake-up of the test thread leaves it, failed the wait instead of answering it. The predicate now judges first; unrelated traffic still cannot carry a wait past the ceiling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(mcp-server): leave a failed diagnostics build and pin the flag-built project (itrous#226, itrous#227)
Owner
|
🤖 Начата автоматическая приёмка — этот pull request взят в работу ИИ-агентом: |
`await_walk_start` ждал первый файл обхода не дольше 60 секунд по часам. Теперь ожидание отсчитывает опросы: под нагрузкой каждый опрос растягивается, а бюджет по-прежнему истекает только тогда, когда обход не начался вообще. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…рки порядка вместо часов Тесты падали под нагрузкой процессора, потому что решали успех по часам: дедлайн в секундах у ожидания состояния, порог в 500 мс у статуса, которому нужен лок, пауза «для прогрева» перед гонкой. Продуктовое поведение не меняется; `McpServer::shutdown` сохраняет пятисекундное ожидание владельцев, добавлен только `shutdown_within`. Ожидания состояний: - `eventually` считает опросы (6000 по 10 мс), а не время; `eventually_within` для ожидания, которое задаётся расписанием повторов (бутстрап, 30 с + 60 с). - Рукописные циклы с дедлайном в тестовом коде переведены на `Patience` (счётчик опросов). В тестовом коде таких циклов не осталось. - `wait_until_watching`, `poll_now`, `tick_now` больше не принимают таймаут: ожидание ограничено общим `STATE_CEILING` (60 с), он защищает от зависания, а не меряет скорость. - Позитивные `recv_timeout`/`timeout` на события с пределами 5–30 с подняты до общего предела. Окна отсутствия (`!recv_timeout(100 мс)`) оставлены: они могут скрыть баг, но не вызвать ложный отказ. - `graph/test_support`: `wait_until_within` и `hold_every_handle` считают опросы. Владельцы и фикстуры: - `tests/tasks.rs`, `tests/task_deadline.rs`: сервер останавливается и ждёт выхода фоновых владельцев до удаления стенда (`Retired`, `shutdown_within`). Раньше фоновая очистка `bsl-overlay-backlog` читала уже удалённые `Толпа*`. - `tests/task_deadline.rs`: перед гейтируемой задачей индекс прогревается, чтобы срок попадал в фазу чтения, а не в фазу построения. - `tests/diagnostics_baseline.rs`: `partial` проверяется после того, как рабочее пространство сообщило, что видит оба модуля (`files_total == 2`). Гонки: - lease: `hold_file_lock_for_test` ждёт освобождения держателя, а не считает, что lock свободен. - `all_status_requests_are_cached_under_held_lease`: вместо порога в 500 мс проверяется журнал дисковых проверок (`disk_checks_on_this_thread`): статус не ходил за lease. - `embedding_fence_*`, `an_embed_pass_in_its_retry_pause_is_not_live_work`: выход пасса ждётся по счётчику `OwnerStop::live`, держатель отпускается после второй попытки fence. - `graph::*` (четыре теста из прогона под нагрузкой): `wait_settled` ждёт не только статус `Ready`, но и проход публикации, пустой слот сборки и отсутствие обхода (`walk_out`). - Три теста без `WALK_GATE` читали общий счётчик обходов: теперь держат гейт. - `a_cancelled_call_frees_the_resident_slot`, `cancelling_a_working_handle_...`: порог «не дольше 3 с» заменён сравнением с тем же ожиданием за незавершённым обходом. Проверки скорости (было 41 `elapsed`-порог в тестовом коде): - Неблокировка доказывается удержанием ресурса до ответа или журналом дисковых проверок (`snapshot`, `hybrid`, `state/mod`). - Ответ сам доказывает результат: `Pending`/`Failed` вместо «быстрее 500 мс». - Остались нижние границы (`>= floor`, `>= 200 мс`), они не нарушаются нагрузкой, и порядка величины 2× (15/30 с, 30/60 с, 300/600 с) — указано в тестах. Проверено: `cargo fmt --check`, `cargo clippy -p mcp-server --all-targets --all-features -D warnings`, `cargo test -p mcp-server --lib` и все интеграционные тесты без нагрузки проходят; с нагрузкой результаты — в описании PR. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- Patience считает шаг в наносекундах: шаг в микросекунды больше не усекается до миллисекунды. - Циклы, которые крутились на `yield_now`, теперь делают шаг по времени: бюджет опросов больше не тратится за миллисекунды (сборка графа, тикер тестов сессии, перенос подписки, `yield_until` в tasks). - Смоук-тест индексации снова ограничен своим бюджетом (150 с), а не общим пределом в 60 с. - Тест shutdown базового сервиса ограничивает возврат десятью производственными ack-таймаутами: блокировку по-прежнему доказывает шлюз, а задержку — верхняя граница. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Бюджет ограничивает только ожидание владельцев. Остановка reference worker, baseline и sweeper выполняется до него без изменений, как и в `shutdown`; документация теперь говорит это прямо. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- Watchdog изолированного фикстурного процесса снова отмеряет часами: это бюджет приёмки (150 с и 30 с), а не ожидание состояния, и сообщение называет секунды. - `walk_out` перенесён выше документа `reserve_probe`, чтобы документация не съехала. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- Проверки задержки ответа на отмену возвращены: `CANCEL_BOUND` (500 мс) как явный контракт скорости в `cancel_tests`, его проверят повторные прогоны под нагрузкой. - Потолки 120 с (resident) и 90 с (владельцы графа) возвращены к прежним значениям: сокращение до 60 с ужесточало тесты там, где ожидание самое длинное. - Контроль `a_cancelled_call_frees_the_resident_slot` меряет холостой вызов на свежем резиденте, который обход не трогал. - Условные ожидания в гейтах `PollGate` и `AnnounceBarrier` списывают бюджет только на таймаут (общий шаг `wait_step`), а пробуждения ограничены отдельным пределом. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…аний) - Ожидание занятости lifecycle в lease-тесте спит между опросами, а не крутится на yield. - Шаг опроса в metadata равен реальной паузе цикла (100 мс): бюджет 60 с, а не 600 с. - Отрицательный контроль владельца снова ждёт 2 с: окно отсутствия не сжимается. - `connect_within` использует свой бюджет (раньше параметр игнорировался). - Бюджеты ожидания из базы (180/120/90 с) возвращены в name_dictionary, outline, references, location_contract и query_validate. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…онде Проверка текста не ловит чистую задержку: статус, который ждёт зонда, но возвращает тот же текст, прошёл бы тест. Возвращена проверка «не дольше 500 мс» как явный контракт скорости (так же, как для отмены поиска). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Ожидания, чьим единственным детектором задержки была граница по времени, снова ограничены исходными значениями: явные проверки `elapsed` (200/500 мс, 1/2/3/5 с, 100 мс) и короткие ожидания «быстро» как счётчики опросов с исходным номиналом (100 и 200 опросов по 10 мс). Контроль `a_cancelled_call_frees_the_resident_slot` снова абсолютный (сосед за живым обходом ждёт больше 1 с): нагрузка только удлиняет такое ожидание, ложного падения не будет. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- `disk_checks_on_this_thread` на безымянном потоке сравнивает с той же меткой `"<unnamed>"`, что и запись: проверка «на этом потоке» не становится пустой. - Ожидания по опросам имеют стенной предел-страховку 20 минут: дорогой опрос не растягивает путь падения на часы. Успешный путь он не касается. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- Тест «владелец, которому велено уйти, отвечает Stopping при занятом движке» запускает вызовы в отдельном потоке и ждёт ответ не дольше секунды: регрессия даёт падение, а не зависание. - Матрица отмены снова проверяет задержку ответа (500 мс) у каждой ячейки; предел 60 с остаётся как страховка от зависания. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
- Бюджет, который не помещается на часах (`shutdown_within(Duration::MAX)`), ждёт срезами по часу, а не паникует при сложении `Instant`. - Комментарий в тесте shutdown называет предел 200 мс тем, чем он является: исходным контрактом задержки (100 мс ack-таймаут в тестовой сборке, предел вдвое больше). - Паника 20-минутного предохранителя в `wait_until` называет предохранитель, а не число опросов. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
… теста Тело теста с #[tokio::test] выполняется на его собственном потоке, а ветка status отвечает инлайн, поэтому фенс статуса записан под именем потока теста. Фильтр по рантайм-воркерам его пропускал: регрессия не ловилась. Теперь считаются фенсы текущего потока. Мутация (фенс в ветке metadata status) валит тест с «a status call fenced the lease». Также: предел shutdown-теста 1 с (десятикратный ack-таймаут, как написано в комментарии), а сообщение probe-теста снова называет фактическую длительность. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ниченное тело опроса Ревью круга 487 (линзы перебор) дало два mid-замечания, оба подтверждены по коду. - OwnerStop::wait_empty с бюджетом, который не помещается в Instant, ждал часовыми срезами, но после первого истёкшего среза при живом владельце возвращал false. Теперь такой бюджет заканчивается только уходом владельцев; ограниченный бюджет ведёт себя как прежде. Цикл вынесен в wait_empty_in_slices(timeout, slice), чтобы тест мог взять срез в 10 мс. - Тело eventually в state/sync.rs спит 200 мс на попытку, а бюджет считал попытки по 10 мс: провал растягивался до 20 минут (HANG_GUARD). Теперь eventually_within(100, …) — около 21 с. Продуктового поведения это не меняет: shutdown по-прежнему ждёт владельцев пять секунд. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
… первой устарелости Тест baseline_parity_partial_stale_error_recovery_and_cancellation под нагрузкой падал в 8 из 20 прогонов базы и в 10 из 20 после прошлых правок: ответ уже был stale, но baseline ещё `full`. Правка файла (drift) наблюдается раньше, чем нечитаемость файла (дыра). Хелпер ждал только stale и отдавал первый такой ответ, а утверждение требовало state `partial`. Теперь хелпер (workspace_until_partial_stale) ждёт обоих фактов по счётчику опросов. Дыра, однажды возникнув, держит partial до лечения, так что ожидание сходится в одну сторону. В сообщение проверки добавлено тело ответа: падение теперь показывает, что именно наблюдалось. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ence test(mcp-server): ожидания тестов не зависят от нагрузки процессора
…space-analysis # Conflicts: # crates/mcp-server/src/lib.rs # crates/test-utils/src/walk_probe.rs
…alysis refactor(workspace): share semantic source updates across LSP and MCP
A lookup that misses the file→root map falls back to the BSL root. That miss is a DashMap absence, so a later registration — a new salsa input — left module metadata memoised against the fallback path. Depend on an epoch read at the miss, and bump it when an insert follows a miss.
Owner
|
🤖 Автоматическая приёмка завершена: изменения приняты, PR влит коммитом 2663eab. |
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.
Graph batches share the full BSL file set but load text and register file-to-root inputs only for the active batch. A borrowed extension form can inherit attributes from a base form in another batch; metadata lookup then required a missing batch-local mapping and panicked, aborting graph publication.
Path lookup now honors an explicit mapping first, then checks exact FileId membership in the published BSL root. This fallback does not load foreign text or revisions, search other roots, or weaken strict source/text getters. Tests cover inherited metadata, removal and restoration in FileSet, explicit-root priority, and graph equality across batch sizes.
Validation on current head
09fb4ef2: GitHub LinuxCheck(formatting, Clippy and full workspace tests),Corpus contract, andWindows MCP transports + secure brokerall passed. The Windows job is its configured transport/cache/lease selection.Before publication integration, the targeted borrowed-form tests (7), path-priority test (1), graph batch-size parity test, formatting and strict Clippy also passed. Full TN runtime graph publication and binary installation were not tested.