fix: cobre o refresh do token OAuth pelo mesmo teto de espera do check-out no boot - #461
Merged
Conversation
…k-out no boot O refresh do token rodava antes do tokio::time::timeout que já protegia o check-out do snapshot no boot: com token expirado e uma rede que engole pacotes, a abertura do app ficava presa pelo pior caso do cliente HTTP (10s de connect + 30s de request x 3 tentativas), não pelos 20s do teto. A URL de refresh (antes fixa em oauth2.googleapis.com) agora é injetável, no mesmo padrão já usado para a base do Drive, e a resolução do cliente (que inclui o refresh) roda sob o MESMO teto que prepare_restore -- o que sobra do orçamento depois de resolver o cliente é o que sobra para o resto do check-out, nunca dois tetos completos somados. Closes #460
This was referenced Aug 14, 2026
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.
O que muda e por quê
O check-out do snapshot no boot (PR #452) já tinha um teto de espera de 20s cobrindo
prepare_restore(busca do manifest + download do snapshot) — mas o refresh do token OAuth, que roda ANTES dessa fase quando o token está expirado, ficava de fora. Com token expirado e uma rede que engole pacotes (portal cativo, VPN degradada), a abertura do app ainda podia ficar presa pelo pior caso do cliente HTTP (10s de connect + 30s de request × 3 tentativas ≈ minutos), não pelos 20s do teto — o residual que a issue #452 já declarava e o #459 não cobria.A cura: a URL do endpoint de refresh (antes fixa em
oauth2.googleapis.com) agora é injetável — mesmo padrão já usado para a base do Drive (transport::production_base_url) — e a resolução do cliente do Drive (que inclui esse refresh) passou a rodar sob o MESMOtokio::time::timeoutque já protegiaprepare_restore. O orçamento é único e compartilhado: o que sobra do teto depois de resolver o cliente é o que sobra para o resto do check-out, nunca dois tetos completos somados (o que dobraria o pior caso em vez de resolvê-lo).Mudanças
src-tauri/src/oauth/token_store.rs:production_token_url()+ variantes_at(refresh_access_token_at,ensure_valid_token_at,ensure_scope_at,ensure_drive_scope_at) com o endpoint de refresh injetável. As funções públicas existentes (ensure_valid_token,ensure_write_scope,ensure_drive_scope) mantêm a assinatura, delegando para as variantes com a URL de produção.src-tauri/src/snapshot/checkout.rs:resolve_drive_client_best_effort_at(endpoint de refresh + base do Drive injetáveis) echeckout_on_open_best_effort_at, que roda a resolução do cliente sob o teto e repassa o orçamento restante paracheckout_on_open_with_deadline.checkout_on_open_best_effort(chamada porlib.rsno boot) mantém a assinatura inalterada.Como verificar
TDD: o teste novo em
checkout.rs(checkout_on_open_best_effort_treats_a_hanging_token_refresh_as_part_of_the_same_boot_deadline) segue o mesmo padrão já usado para o manifest pendurado — umTcpListenerque aceita a conexão e nunca responde, agora no endpoint de refresh — e prova que o teto injetado (200ms) é quem interrompe, não o timeout de produção do cliente HTTP: o teste conclui em milissegundos, não minutos. Um segundo teste emtoken_store.rsconfirma querefresh_access_token_atde fato usa a URL injetada, isolado do timeout.100% verde (1401 testes da lib, incluindo a regressão de pool de 1 conexão já existente para os caminhos de export/restore).
Closes #460