Skip to content

fix(league): parar de reemitir a sessao de champ select a cada tick do timer - #268

Merged
tonhowtf merged 2 commits into
mainfrom
hotfix/league-freeze
Jul 30, 2026
Merged

fix(league): parar de reemitir a sessao de champ select a cada tick do timer#268
tonhowtf merged 2 commits into
mainfrom
hotfix/league-freeze

Conversation

@tonhowtf

Copy link
Copy Markdown
Owner

O que

Hotfix do travamento + o histórico completo que faltava.

  1. O evento league-champ-select só é emitido quando muda algo que a interface lê.
  2. Os pollers da partida ao vivo ganham guarda de reentrância.
  3. Histórico: runas e feitiços por jogador, os sete itens, estatísticas completas, e clicar num nome abre as últimas partidas daquele jogador.

A causa do travamento

O cliente republica a sessão de champ select várias vezes por segundo — só o relógio da fase (timer.adjustedTimeLeftInPhase) já muda a cada tick. O ws.rs reemitia o objeto inteiro em cada uma dessas atualizações, e o frontend fazia champSelect = e.payload, substituindo um estado grande. Como os oito painéis do league ficam sempre montados (decisão deliberada, para preservar estado entre abas), cada evento forçava todos a reavaliar seus derivados e redesenhar. Isso satura a thread da UI da webview — e como é a mesma thread do app inteiro, a janela para de responder a cliques e não dá para trocar de menu. Bate com o relato: acontece "do nada", sempre no League.

O agravante: o setInterval de 4s chamava refreshPhaseData sem verificar se a rodada anterior tinha terminado. Com o cliente lento, cada tique enfileirava mais três requisições, e as respostas se acumulavam na mesma thread.

Duas correções independentes, porque as duas causas são reais:

  • Coalescing por impressão digital (champ_select_fingerprint): cobre actions (id, campeão, completed, isInProgress), campeões e intenções de pick dos dois times, banco, trocas e swaps. O relógio fica de fora. Se a impressão digital não mudou, o evento é descartado; um batimento de 1,5s garante que a interface nunca fique parada por causa de uma mudança que a impressão digital não cobriu.
  • Guardas de reentrância em loadLiveMetrics, loadLiveEvents, loadCooldowns e no próprio refreshPhaseData: um tique que chega com o anterior em voo é descartado, não enfileirado.

Não consegui reproduzir o travamento aqui (sem cliente de LoL rodando nesta máquina), então isto é correção por diagnóstico do mecanismo, não por observação do bug. Se voltar a travar, o próximo suspeito é o volume de re-render dos painéis sempre montados — a correção seria desmontar os painéis inativos, ao custo de perder estado ao trocar de aba.

O histórico completo

  • Runas por jogador: keystone e estilo secundário no placar, com os ícones vindos de /lol-perks/v1/perks (que já é cacheado como patch-static). O payload traz também os 6 perks e os 3 stat mods, prontos para uma visão detalhada.
  • Ver histórico de quem jogou com você: participantIdentities[].player.puuid dá o puuid de cada participante, então clicar no nome abre as últimas 10 partidas dele numa gaveta. Isto entrega o item D7, que eu tinha descartado no PR feat(league): definir preferencia de rota no lobby #250 achando que o puuid não estava disponível no payload — estava, eu tinha olhado no lugar errado.
  • Todas as informações: dano causado (com quebra físico/mágico/verdadeiro no payload), dano recebido, dano mitigado, cura, escudo em aliados, dano a objetivos e torres, ouro/min, CS/min, visão, wards colocadas/destruídas/de controle, tempo de CC, melhor sequência, multikills, first blood, primeira torre, nível e os 7 slots de item.

Como testar

  1. cd src-tauri && cargo test -p omniget league — 3 testes novos do coalescing (77 no total): sessão que só avançou o relógio tem a mesma impressão digital; qualquer mudança que os painéis leem muda a impressão; sessão vazia não quebra.
  2. Entrar em champ select e deixar rodando: a interface continua respondendo, e o painel atualiza quando alguém escolhe ou bane.
  3. Histórico → expandir uma partida: runas, feitiços, itens e a linha completa de estatísticas por jogador.
  4. Clicar no nome de qualquer jogador do placar: a gaveta mostra as últimas partidas dele.

Plataformas

  • Windows: nenhuma diferença de comportamento (o coalescing é no backend, comum aos dois)
  • macOS testado (cargo test 77, pnpm test 58, pnpm check 0 erros)

Estado

stable — o hotfix não tem flag: é correção de um comportamento que nunca foi intencional.

Risco & rollback

Risco ToS: nenhum (menos tráfego, não mais). Rollback: reverter o commit; o comportamento anterior volta, travamento incluído.

Débito deixado

  • A impressão digital é uma lista de campos escrita à mão. Se o cliente passar a expor algo novo que a UI leia, é preciso lembrar de incluir — o batimento de 1,5s limita o estrago a um atraso, não a um dado errado.
  • O evento league-lobby não foi coalescido; o lobby muda muito menos, mas o padrão está pronto se precisar.
  • A quebra de dano por tipo e os 6 perks completos vão no payload mas ainda não aparecem na tela.

tonhowtf added 2 commits July 30, 2026 13:21
…o timer

O cliente republica a sessao varias vezes por segundo — so o relogio da fase ja
muda a cada tick. Reemitir o objeto inteiro nessa frequencia inunda a webview:
cada evento troca um estado grande e forca os oito paineis montados a redesenhar,
o que trava a janela toda e impede ate trocar de menu.

Agora o evento so sai quando muda algo que a interface le (actions, campeoes,
banco, trocas), com um batimento de 1,5s para nunca ficar parado. Os pollers da
partida ao vivo ganham guarda de reentrancia: um tique que chega com o anterior
em voo e descartado em vez de enfileirado.

Junto, o historico ganha o que faltava: runas e feiticos por jogador, os sete
itens, e as estatisticas completas (dano causado/recebido/mitigado, cura,
objetivos, ouro por minuto, CS por minuto, visao, wards, tempo de CC, melhor
sequencia, multikills, first blood e primeira torre). Clicar no nome de qualquer
jogador do placar abre as ultimas partidas dele.
@tonhowtf
tonhowtf force-pushed the hotfix/league-freeze branch from 4965ad2 to cf7344c Compare July 30, 2026 16:25
@tonhowtf
tonhowtf changed the base branch from feat/akari-registry-wiring to main July 30, 2026 16:25
@tonhowtf
tonhowtf merged commit 0030100 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