Samuel Arendt

O atraso do WordPress 7.0 expõe o custo arquitetural do tempo real

WordPress 7.0 RC1 atrasou. E o motivo é mais técnico do que parece.

A release candidate estava marcada pra 19 de março. Foi empurrada pra hoje, 24 de março. Três problemas forçaram o adiamento: performance da colaboração em tempo real, otimização de mídia no client-side, e tamanho do pacote de release.

O mais interessante é o primeiro.

A colaboração em tempo real é a feature principal do WordPress 7.0. É a conclusão da fase 3 do projeto Gutenberg. Funciona com CRDT (Conflict-free Replicated Data Types) e sincronização via HTTP polling. O problema? Os dados de sincronização ficam no post_meta, e cada atualização invalida o cache de queries de posts do WordPress inteiro. Com um usuário no editor, o sistema faz polling uma vez por segundo. Com dois, quatro vezes por segundo.

Na prática, ativar a colaboração em tempo real desabilita silenciosamente o cache persistente de posts. Num site com tráfego, isso tem impacto direto em performance.

A solução que estão buscando é mover os dados de RTC pra uma tabela dedicada no banco, separando completamente do post_meta. Mas isso é uma mudança arquitetural pesada pra fazer entre um beta e um RC.

O resultado: a feature vai vir desativada por padrão no RC1. Opt-in em Configurações > Escrita. Quem tinha ligado durante o beta vai encontrar desligado depois de atualizar.

A data final de lançamento continua 9 de abril, no Contributor Day do WordCamp Asia. Mas a decisão de ativar RTC por padrão só vai ser tomada no RC2.

O que o poll faz com o cache de posts

Peter Wilson documentou no Trac que, com RTC ligado e o editor aberto, o WordPress opera como se o cache persistente de queries de posts estivesse desligado. Presença (wp_sync_awareness) e updates (wp_sync_update) ficam em post_meta. Qualquer escrita ali dispara invalidação ampla, inclusive de queries que não têm relação com o post aberto.

Um editor: um poll por segundo. Dois: quatro por segundo. Num install fresco, Wilson mediu 60 requests por minuto e 110 a 120 KB só de abrir o Hello World. Com dois colaboradores, da ordem de 480 requests por minuto e cerca de 900 KB. O Heartbeat, que o core já usa para lock, dispara no máximo a cada 10 segundos e desacelera com a aba em segundo plano. O RTC, na forma que ele encontrou, seguia a cada segundo com a aba aberta e ninguém digitando.

Na reunião do time de hosting, GoDaddy descreveu requests a cada 250 ms por editor, impossíveis de cachear. WP Engine apontou contenção de recurso e risco de race. Para site com object cache, a feature ligada vira um gerador de invalidação enquanto alguém deixa o Gutenberg aberto.

Critério para ligar colaboração onde já existe tráfego

No RC1 a feature vem desligada. Opt-in em Configurações, Escrita. Quem ligou no beta encontra desligado depois do update. Em site com object cache persistente e page cache na frente, esse default é o único que faz sentido até a tabela nova existir no pacote que você realmente vai rodar.

Ligue RTC onde a coedição é rotina: redação, agência, time que trabalha no mesmo post. Site de um autor, loja, marketing com um editor por vez paga o poll e ganha pouco. Há um caso estreito, levantado no Trac, de quem abre o mesmo post em várias abas ou aparelhos. Mesmo aí, meça antes de virar política.

Com a feature ligada e o editor aberto, compare taxa de invalidação, hit ratio do object cache, requests por minuto no endpoint de sync, CPU e I/O do banco, e a mesma URL de front com o editor fechado. Se a listagem de posts no site público derrete porque alguém foi almoçar com o Gutenberg aberto, o custo operacional já apareceu.

A tabela dedicada e o que o RC1 ainda deixa em aberto

A direção técnica é uma tabela só para o sync, discutida como wp_collaboration. Matt Mullenweg, em geral contrário a tabelas novas no core, aceitou esta como primitiva para colaboração e sync futuros. A última adição nesse espírito foi wp_termmeta, no 4.4, em dezembro de 2015.

Tirar o sync do post_meta evita os hooks de invalidação, reduz a race de dois editores gravando no mesmo milissegundo e deixa a compactação de dados velhos como operação atômica. Entre beta e RC, isso é mudança pesada. Por isso o default ficou para o RC2.

Multisite ainda tem aresta: administrador de subsite pode ligar RTC sem conseguir disparar upgrade de banco. Há também a ideia, em ticket separado, de marcar certas chaves de post_meta como não consultáveis para não invalidar cache. Wilson preferiu não misturar isso na correção atual. Não ative em rede até o caminho de schema estar claro no release notes que você vai aplicar.

A data de 9 de abril no WordCamp Asia é calendário de lançamento. Default ligado ou desligado é decisão de arquitetura. As duas podem divergir.

Teste com o editor ocioso e o cache ligado

O Make WordPress Test pediu exercício com conteúdo real, mais de um colaborador, blocos customizados e plugins. Polling HTTP tem lag. O canal da feature e a tracking issue no GitHub existem para o que travar e o que fluir.

Para um site que já serve tráfego, o teste útil começa magro: um editor, depois dois, object cache ligado, plugin de page cache na frente, Heartbeat no comportamento atual. Deixe o editor aberto dez minutos sem digitar. Se o poll não arrefecer no pacote candidato, ligue a feature só com horário marcado e rollback.

Um ajuste no cliente já reduz poll com a aba inativa, e a taxa deve ficar filtrável para hosts. Nenhum dos dois substitui sair do post_meta. Até a tabela existir no zip que você vai atualizar, trate colaboração em tempo real como opt-in, mesmo que a fase 3 do Gutenberg continue sendo a headline da 7.0.

Referências

#Arquitetura, #Performance, #Qualidade de Software