Skip to content

fix: cobre o refresh do token OAuth pelo mesmo teto de espera do check-out no boot - #461

Merged
johnlaff merged 1 commit into
mainfrom
impl/issue-460
Aug 14, 2026
Merged

fix: cobre o refresh do token OAuth pelo mesmo teto de espera do check-out no boot#461
johnlaff merged 1 commit into
mainfrom
impl/issue-460

Conversation

@johnlaff

Copy link
Copy Markdown
Owner

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 MESMO tokio::time::timeout que já protegia prepare_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) e checkout_on_open_best_effort_at, que roda a resolução do cliente sob o teto e repassa o orçamento restante para checkout_on_open_with_deadline. checkout_on_open_best_effort (chamada por lib.rs no 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 — um TcpListener que 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 em token_store.rs confirma que refresh_access_token_at de fato usa a URL injetada, isolado do timeout.

npm run rust:check   # cargo check + rustfmt --check + clippy -D warnings + cargo test --all-targets --all-features

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

…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
@johnlaff
johnlaff merged commit 250bf3b into main Aug 14, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Snapshot no Drive: teto do boot só vale depois do refresh do token OAuth

1 participant