Rails caminha para suporte a Ractor e ajusta ordem no cache multi-chave
O boletim This Week in Rails detalha commits que tornam configurações compartilháveis entre Ractors, corrigem vazamento de conexão e preservam a ordem de chaves no fetch_multi. O que isso muda para quem mantém Rails em produção.

O boletim This Week in Rails, assinado por Vipul A M, reúne uma leva de commits que interessa menos ao marketing e mais a quem mantém aplicação Rails de verdade em produção. Dois temas puxam a fila: o avanço gradual do framework rumo ao suporte a Ractor e um punhado de correções em cache, conexão e adapter PostgreSQL↳PostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data → que resolvem dores concretas. Vale destrinchar cada um, porque nenhum deles vem com fanfarra e todos têm trade-off.
Ractor: paralelismo de verdade, um pedaço por vez
Ractor é o modelo de concorrência do Ruby↳Ruby3 conteúdosComo migrei meus testes automatizados de Java para Ruby… Será que fiz bem?Dev (Back & Front) · jun 2019Refatoração em RubyDev (Back & Front) · mai 20197 exemplos de linguagens de programação server-sideGestão Dev & TI · jun 2024Ver tudo em Dev (Back & Front) → que promete paralelismo real (fugindo do GVL, o Global VM Lock) ao isolar estado entre atores. O problema histórico: para um objeto ser compartilhado entre Ractors, ele precisa ser frozen e shareable. Boa parte da configuração interna do Rails não era, e isso na prática inviabilizava rodar Rails sob Ractors sem esbarrar em erro de objeto não compartilhável.
A novidade da semana é que o Rails tornou compartilháveis entre Ractors a configuração de controllers, os settings do Action View, os commit callbacks do Active Record e a configuração de time zone. Além disso, o schema context do Active Record não trava mais (deadlock) ao inicializar atributos, e os event reporters passam a usar armazenamento por-Ractor quando rodam fora do Ractor principal.
Nenhum desses commits, sozinho, faz seu app rodar em Ractors amanhã. O recado é de direção: o framework está limpando o caminho, uma subsistema por vez. Para o time brasileiro que hoje escala Rails com Puma multi-processo ou com fibers (Falcon), o horizonte de paralelismo real dentro de um único processo continua distante, mas menos utópico. Quem quiser experimentar precisa lembrar que gems de terceiros e código de aplicação também precisam ser Ractor-safe, o que ainda é a exceção no ecossistema.
Vazamento de conexão no Action Controller Live
Esse é do tipo de bug que só aparece em produção sob carga. O TypeCaster passou a usar with_connection, devolvendo a conexão ao pool imediatamente em vez de depender da limpeza do executor. O sintoma corrigido era um vazamento de conexão em ações ActionController::Live, aquelas usadas para streaming (SSE, respostas longas).
A lógica por trás importa: em uma ação Live, a requisição pode ficar aberta por muito tempo. Se o checkin da conexão fica pendurado no ciclo do executor, você segura uma conexão do pool por toda a duração do stream, sem necessidade. Em apps com pool pequeno e vários clientes conectados a endpoints de streaming, isso esgota o pool e derruba requisições novas. Trocar para with_connection fecha esse buraco devolvendo a conexão assim que o type casting termina.
Ordem preservada no fetch_multi com local cache
Esse é sutil e pode ter mordido gente sem que percebesse. O ActiveSupport::Cache::Strategy::LocalCache#fetch_multi retornava primeiro os hits locais e depois os misses, alterando a ordem que o chamador havia pedido. Agora ele devolve as chaves na ordem original, igual ao Store#fetch_multi.
Por que isso quebra código na prática? Porque muita gente faz algo como:
results = Rails.cache.fetch_multi(*ids) { |id| load(id) }
results.values # esperava a ordem de idsSe parte dos ids estava no local cache (dentro de um bloco de request com with_local_cache) e parte não, o values vinha embaralhado, hits primeiro. Código que confiava na correspondência posicional entre entrada e saída produzia resultado errado silenciosamente, o pior tipo de bug. A correção alinha o comportamento das duas camadas de cache. Se você tinha workaround reordenando manualmente, dá para removê-lo, mas confira antes de assumir.
Ajustes no adapter PostgreSQL
Duas mudanças no lado do Postgres. A primeira: o adapter agora aceita a opção error_verbosity no database.yml, aplicada na configuração de cada conexão.
production:
adapter: postgresql
error_verbosity: <%= PG::PQERRORS_TERSE %>Controlar a verbosidade de erro do Postgres é útil para reduzir ruído em logs ou, ao contrário, ganhar detalhe em debugging. É um daqueles ajustes finos que só quem já apanhou de log gigante de erro em produção valoriza.
A segunda é uma correção de robustez: disable_referential_integrity agora restaura os triggers desabilitados a partir de um bloco ensure. Antes, se algo levantasse exceção dentro do bloco, os triggers podiam ficar desabilitados após a saída, deixando a integridade referencial silenciosamente desligada. É o tipo de armadilha que só se descobre quando dados inconsistentes já entraram.
Testes mais honestos e outras correções
Uma configuração nova ajuda a caçar dependências acidentais de ordem nos testes:
config.active_record.shuffle_unordered_selects = trueCom ela, resultados de SELECT sem ORDER BY são embaralhados, expondo testes que passavam por sorte porque o banco devolvia as linhas numa ordem conveniente. É uma faca de dois gumes bem-vinda: vai fazer testes verdes ficarem vermelhos, mas justamente os que estavam mentindo. O trade-off é ligar em CI e encarar a limpeza, não em cima de um deploy.
Outros pontos que merecem atenção antes de subir versão:
- Active Storage agora depende do Marcel 2, com detecção de MIME mais ampla. Arquivos recém-analisados podem receber content types canônicos onde o Marcel 1 devolvia aliases. Blobs existentes mantêm o tipo armazenado, mas se você compara strings de content type em algum lugar, revise antes de atualizar.
- Compatibilidade com JSON 3.0: o Active Support passou a mandar opções para
JSON.parsecomo keyword arguments, exigência da gem JSON 3.0. Foram corrigidos tambémActiveRecord::Coders::JSONe fixtures criptografadas em colunas JSON. - Timeout de 15 minutos nos jobs do GitHub Actions gerados em apps novos. Suíte grande? Aumente ou remova o limite.
- Remoção de join redundante ao mesclar associação
has_many :throughcom escopo, gerando query mais enxuta.
O que fica em aberto
Duas guias novas estão abertas para revisão da comunidade: o aguardado guia de Hotwire e uma reescrita do guia Securing Rails. Foram 25 contribuidores ao codebase na semana. Para quem mantém Rails em produção, a leitura útil deste boletim não é o Ractor (ainda longe do dia a dia), e sim o combo cache/conexão/PostgreSQL: são exatamente os cantos onde bug de ordenação, vazamento de pool e integridade referencial silenciosa custam caro. Revisar comparações de content type e o comportamento do fetch_multi antes do próximo bump é o gesto prático que este changelog pede.
Fonte: Ruby on Rails Blog
Este artigo foi escrito por Bisneto Braga, colunista de back-end. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
GitHub Copilot ganha configurações granulares de code review automatizado
Uma página dedicada de configurações pessoais e um novo padrão de esforço de revisão em nível de enterprise chegam a todos os planos do Copilot, inclusive Business.














