fix: reverte automaticamente para a salvaguarda quando a reabertura falha na resolução de conflito use_remote - #458
Merged
Merged
Conversation
…na resolução de conflito use_remote resolve_conflict_use_remote_core trocava o arquivo do banco pelo snapshot do outro aparelho e, se a reabertura em seguida falhasse (I/O transitório, disco cheio na migração), devolvia erro deixando o banco ativo preso no conteúdo quebrado — mesmo com uma salvaguarda íntegra do conteúdo local ao lado, criada pela própria troca. O check-out no boot já resolvia essa mesma janela via reopen_after_swap_or_rollback (issue #446); esta mudança expõe essa função do módulo checkout e a reusa aqui, revertendo automaticamente para a salvaguarda em vez de deixar o dono com um banco inutilizável após reiniciar. requires_restart continua sempre true nesta função, em qualquer desfecho: o pool recebido já foi fechado no ponto de não-retorno antes da troca de arquivo, e não há hoje como substituir o pool gerenciado pelo Tauri no meio de uma sessão — a reversão evita corrupção, não o reinício em si.
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 quê e por quê
resolve_conflict_use_remote_core(resolução de conflito do snapshot no Drive, escolha "usar o outro aparelho") faz o mesmo swap+reopen do check-out no boot: baixa o snapshot do outro aparelho, fecha o pool local, troca o arquivo do banco atomicamente e reabre um pool novo no arquivo trocado. Se a troca tivesse sucesso mas a reabertura do conteúdo recém-trocado falhasse (I/O transitório, disco cheio durante a migração), a função devolvia erro e o banco ativo ficava preso no conteúdo quebrado — mesmo havendo, ao lado, uma salvaguarda íntegra do conteúdo local de ANTES da troca, criada pela própriaswap_active_db_atomically, pronta para reversão automática.O mesmo problema já tinha sido corrigido no check-out do boot (#446), via
checkout::reopen_after_swap_or_rollback. Este PR expõe essa função (antes privada ao módulocheckout) e a reusa aqui, em vez de duplicar a lógica.Mudança
checkout::reopen_after_swap_or_rollbacke o enumReopenOutcomepassam a serpub(crate).ReopenOutcome::RolledBackagora descreve só O QUE aconteceu (reabertura falhou, revertido com sucesso) — a cláusula de "o que fazer a seguir" é específica de cada chamador:commit_restore(boot) mantém a frase original ("o snapshot remoto será tentado de novo na próxima abertura");resolve_conflict_use_remote_core(conflito) agora diz que a disputa segue pendente para o dono escolher de novo depois de reiniciar.resolve_conflict_use_remote_coretroca a chamada direta aopen_migrated_poolporreopen_after_swap_or_rollback, tratando os três desfechos (Reopened,RolledBack,Errfatal).Decisão registrada (issue #451, item 1):
requires_restartcontinua sempretruenesta função, em qualquer desfecho — inclusive quando a reversão automática funciona. O pool que a função recebe já é fechado no ponto de não-retorno, antes da troca de arquivo, e não existe hoje um jeito de substituir o pool gerenciado pelo Tauri (State<SqlitePool>) no meio de uma sessão — sóapp.manage()dentro dosetup()faz isso. Mudar esse contrato só para o caminho de reversão exigiria plumbing novo fora do escopo deste follow-up; a reversão evita deixar o dono com um banco corrompido/inutilizável após reiniciar, mas não evita o reinício em si. Escolhido pelo menor escopo, por simetria com o resto da função (que já sempre pede reinício, mesmo no caminho feliz).Decisão registrada (issue #451, item 2): compartilhamento via exposição
pub(crate)da função já existente e exaustivamente testada emcheckout.rs, em vez de duplicar a lógica de reversão.TDD
Teste novo em
snapshot_cmds.rs:resolve_use_remote_rolls_back_to_the_local_safeguard_when_the_remote_content_wont_reopen. Constrói um snapshot remoto SQLite estruturalmente válido (passaPRAGMA integrity_check), mas com o checksum de uma migração corrompido de propósito —sqlx::migrate!().run()recusa reabrir (VersionMismatch) mesmo com o arquivo íntegro, reproduzindo de ponta a ponta (com HTTP mockado) a mesma classe de falha que a issue descreve ("I/O transitório, disco cheio na migração"). O teste confirma que, depois do erro, o banco ativo reaberto do zero contém o conteúdo LOCAL de antes da troca — nunca o remoto quebrado, nunca um banco vazio.Como verificar
cargo test --lib snapshot— 112 testes do módulo, incluindo o novo.cargo test --lib snapshot_cmds— 19 testes, incluindo o novo.npm run check— gate completo (format, lint, typecheck, testes JS, build, rust:check, privacy:scan, comment:hygiene, ui:audit) verde.Closes #451