Skip to content

fix(league): parar de redesenhar os oito paineis a cada evento - #270

Merged
tonhowtf merged 1 commit into
mainfrom
fix/league-freeze-round2
Jul 30, 2026
Merged

fix(league): parar de redesenhar os oito paineis a cada evento#270
tonhowtf merged 1 commit into
mainfrom
fix/league-freeze-round2

Conversation

@tonhowtf

Copy link
Copy Markdown
Owner

O que

Segunda rodada do travamento. A primeira (#268) atacou um evento; a causa é estrutural e tem cinco fontes, corrigidas aqui.

Por que a primeira correção não bastou

A página monta os oito painéis ao mesmo tempo e os mantém montados de propósito, para preservar estado entre abas. Isso significa que qualquer mudança de estado — não só o champ select — faz os oito reavaliarem derivados e redesenharem. A webview que desenha esses painéis é a mesma que desenha a navegação do app: saturá-la congela a janela inteira, e é por isso que não dá para clicar em nada nem trocar de menu.

Throttlar só o champ select reduziu uma das fontes. Sobraram: lobby (republica a cada tique da estimativa de fila), ready check (a cada tique do contador), e o próprio volume de trabalho por evento.

As cinco correções

  1. Painel inativo não renderiza. Mantém instância, estado e efeitos — o auto-runas continua funcionando de qualquer aba, e os timers de feitiço não se perdem — mas o custo de desenho cai de oito painéis para um. É a correção estrutural; as outras quatro reduzem a frequência com que ela é exercitada.
  2. LiveTab estava montado duas vezes. Duplicata introduzida na resolução manual de conflito do fix: consertar o main, quebrado pelas minhas resoluções de conflito #262: duas instâncias completas, cada uma com seus setInterval e efeitos.
  3. Coalescing para lobby e ready check, com a mesma impressão digital do champ select — o lobby ignora a estimativa de fila, o ready check ignora o contador.
  4. Filtro por uri antes do parse. A assinatura do WebSocket é OnJsonApiEvent, ou seja, o firehose de todos os plugins do cliente; cada mensagem era parseada por inteiro para depois ser descartada. Agora um contains sobre o texto cru decide antes de alocar.
  5. Settings em cache por 2s. league_settings() era chamado a cada evento e cada chamada relia e parseava o arquivo de settings do disco.

Bônus: get_client() deixou de segurar o mutex do cliente cacheado durante a checagem de rede, o que punha todos os comandos do league em fila atrás de uma ida e volta de até 10s.

Como testar

  1. cd src-tauri && cargo test -p omniget league — 3 testes novos (80 no total): o filtro por uri aceita as nossas e rejeita hovercard/loot; a impressão digital do lobby ignora a estimativa e reage a entrada/saída e troca de rota; a do ready check ignora o relógio e reage à resposta.
  2. Abrir a página do League e ficar na fila, entrar em champ select e jogar uma partida: a janela deve continuar respondendo, e trocar de menu deve funcionar a qualquer momento.
  3. Trocar de aba e voltar: busca, timers de feitiço e partidas expandidas continuam onde estavam (a instância não é destruída).
  4. Ligar auto-runas e ficar em outra aba durante o champ select: as runas continuam sendo aplicadas.

Plataformas

  • Windows: as correções são de backend e de render, sem código específico de SO
  • macOS testado (cargo test 80, pnpm test 58, pnpm check 0 erros)

Estado

stable — sem flag.

Risco & rollback

Risco ToS: nenhum (o app faz menos trabalho e menos requisições). Rollback: reverter o commit único.

O que ainda não sei

Continuo sem conseguir reproduzir o travamento — não há cliente de LoL nesta máquina. As cinco fontes acima são reais e mensuráveis por leitura do código, mas não posso afirmar que cobrem o caso do usuário. Se voltar a travar, o próximo passo não é adivinhar de novo: é instrumentar. O caminho seria registrar, em memória e sob o painel de debug, a contagem de eventos emitidos por segundo e a duração dos comandos — o que transformaria o próximo relato em dado em vez de hipótese.

…ver o LiveTab duplicado

O travamento nao vinha de um evento so. A pagina monta os oito paineis ao mesmo
tempo e os mantem montados de proposito, para preservar estado entre abas — mas
isso faz cada mudanca de estado reavaliar e redesenhar os oito. Como a webview
desenha tambem a navegacao do app, saturar essa thread congela a janela inteira.

Agora o painel inativo mantem instancia, estado e efeitos, mas nao renderiza:
o auto-runas continua funcionando de qualquer aba e o custo de desenho cai para
um painel.

O LiveTab estava montado duas vezes desde a resolucao manual de conflito — duas
instancias com seus proprios intervalos e efeitos.

No backend, tres fontes de carga a menos: lobby e ready check passam pelo mesmo
coalescing do champ select (o lobby republica a cada tique da estimativa de fila,
o ready check a cada tique do contador); as mensagens da LCU sao filtradas por uri
antes do parse, porque a assinatura e o firehose de todos os plugins do cliente; e
as settings ficam em cache por 2s, em vez de reler o arquivo a cada evento.

Por fim, get_client deixa de segurar o mutex durante a checagem de rede, que punha
todos os comandos do league em fila atras de uma ida e volta.
@tonhowtf
tonhowtf merged commit cc22669 into main Jul 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant