O Rails 6.0.0 foi lançado há 25 dias, então acho que é hora de atualizar o Discourse Houve algumas etapas que precisei realizar para fazer isso funcionar.
Corrigir testes quebrados
Adicionar método vazio trigger_transactional_callbacks? em lib/mini_sql_multisite_connection.rb
UrlHelper está carregando por padrão ActionView::Helpers::UrlHelper em vez de lib/UrlHelper. Resolvi isso adicionando :: na frente, no entanto, o que vocês acham sobre mudar o nome dessa classe?
No Rails 5.2.3, o MigrationContext aceitava um argumento; no 6.0.0, um esquema adicional é necessário
Corrigir aviso de constante já inicializada (TRADITIONAL_ESCAPED_CHAR, RFC_5987_ESCAPED_CHAR). Antes de removê-los, confirmei que os valores em ActionPack são os mesmos
Usar o autoloader clássico como primeira etapa antes do Zeitwerk
Corrigir migrações no Rails 6.0.0 - o Rails mais recente não permite erro de migração antiga (você não pode definir uma coluna já definida como ‘integer’)
Realizei testes de fumaça para confirmar que o Discourse funciona conforme o esperado. Além disso, executei testes de desempenho para garantir que não haja regressão (usei as 500 iterações padrão).
Teste
Rails 5.2.3
Rails 6.0.0
Porcentagem
categories-50
27
24
88,89%
categories-75
31
26
83,87%
categories-90
36
37
102,78%
categories-99
52
50
96,15%
home-50
27
26
96,30%
home-75
30
28
93,33%
home-90
39
38
97,44%
home-99
53
55
103,77%
topic-50
35
27
77,14%
topic-75
36
29
80,56%
topic-90
37
39
105,41%
topic-99
56
50
89,29%
categories_admin-50
47
47
100,00%
categories_admin-75
54
59
109,26%
categories_admin-90
64
66
103,13%
categories_admin-99
132
116
87,88%
home_admin-50
47
46
97,87%
home_admin-75
51
56
109,80%
home_admin-90
63
64
101,59%
home_admin-99
110
97
88,18%
topic_admin-50
50
49
98,00%
topic_admin-75
58
59
101,72%
topic_admin-90
65
67
103,08%
topic_admin-99
113
86
76,11%
load_rails
2593
2618
100,96%
rss_kb
318800
287332
90,13%
pss_kb
306913
275378
89,73%
Média
89,31%
Vou criar um pull request com todas as alterações mencionadas acima. Por favor, me avise se quiser que eu ajuste algo ou realize testes adicionais para garantir que tudo funcione conforme o esperado.
Você pode colocar isso em uma tabela Markdown com a variação percentual? Uma olhada rápida mostra que não houve muitas mudanças, o que é ótimo.
No que diz respeito aos plugins, temos uma tarefa rake que instala todos os plugins oficiais. Você pode executá-la e garantir que as especificações dos plugins passem no Rails 6? (O comando rake plugin:spec deve resolver)
Atualizei a postagem original para exibir a tabela. Obrigado por me indicar as especificações dos plugins. Vi que duas especificações falharam no Travis; vou analisar e corrigi-las.
Há dois números aqui que estou achando muito interessantes:
O RSS na versão 6.0 é quase 10% melhor.
O tópico (tempo mediano) — que é nossa rota mais comum — é 22% mais rápido.
Isso é uma melhoria de desempenho realmente séria. Você consegue medir consistentemente 22% de velocidade a mais em topic-50? Pode confirmar se a página real está sendo renderizada corretamente?
Executei o benchmark 3 vezes e, desta vez, os resultados são menos espetaculares. Meu fluxo é digitar ruby script/bench.rb na branch correta master ou rails6, pressionar Enter e não tocar no teclado para não afetar os resultados
| | topic-50 | RSS |
| — | — | — | — |
| 5.2.3 | 50 | 322852 |
| 5.2.3 | 50 | 309684 |
| 5.2.3 | 50 | 346376 |
| Média | 50 | 326304 |
| 6.0.0 | 49 | 328844 |
| 6.0.0 | 49 | 321824 |
| 6.0.0 | 49 | 283584 |
| Média | 49 | 311417 |
Também conectei meu servidor de desenvolvimento ao banco de dados de desempenho para garantir que a página do tópico esteja correta. A captura de tela abaixo parece boa para mim
Gostaria de ter sua opinião sobre uma correção.
Baixei todos os plugins, mas uma nova especificação está falhando em comparação com a master (./plugins/discourse-data-explorer/spec/controllers/queries_controller_spec.rb:32)
1) DataExplorer::QueryController quando desativado nega cada requisição
Failure/Error: render 'default/empty'
ActionView::Template::Error:
número incorreto de argumentos (2 fornecidos, 1 esperado)
Posso aplicar um monkey patch no rspec-rails com um novo arquivo em lib/freedom_patched/rspec-rails.rb, mas gostaria de garantir que essa seja a melhor abordagem.
Acho que essa é a última mudança que está impedindo a fusão do Rails 6.
Além disso, notei que essa especificação está quebrada, mas ela também está quebrada na master. Posso tentar corrigi-la (./plugins/discourse-calendar/spec/jobs/update_holiday_usernames_spec.rb:14)
Por fim, atualizei o rspec-rails para a versão 4.0.0.beta2 e ele funciona bem na minha máquina local. O Travis teve alguns problemas, no entanto, vejo os mesmos problemas em outros pull requests, então não acredito que isso esteja correlacionado com a atualização do rspec-rails.
Minha única preocupação (e algo que gostaria de esclarecer) é que parece haver threads “descontroladas” por alguns segundos regularmente nos web workers.
Isso é resultado de um novo código no Rails 6 que protege o acesso a variáveis vinculadas à thread, determinando se é possível usar ou não prepared statements.
No Discourse, não usamos prepared statements de forma alguma, então esse patch não é algo de que precisamos.
# frozen_string_literal: true
class Thread
attr_accessor :origin
end
class ThreadDetective
def self.test_thread
Thread.new { sleep 1 }
end
def self.start(max_threads)
@thread ||= Thread.new do
self.new.monitor(max_threads)
end
@trace = TracePoint.new(:thread_begin) do |tp|
Thread.current.origin = Thread.current.inspect
end
@trace.enable
end
def self.stop
@thread&.kill
@thread = nil
@trace&.disable
@trace.stop
end
def monitor(max_threads)
STDERR.puts "Monitorando threads em #{Process.pid}"
while true
threads = Thread.list
if threads.length > max_threads
str = +("-" * 60)
str << "#{threads.length} encontrados no processo #{Process.pid}!\n"
threads.each do |thread|
str << "\n"
if thread.origin
str << thread.origin
else
str << thread.inspect
end
str << "\n"
end
str << ("-" * 60)
STDERR.puts str
end
sleep 1
end
end
end
Em seguida, integrei no unicorn um require desta classe no after_fork e executei ThreadDetective.start(14)
A classe observou diligentemente cada vez que uma thread era criada usando um TracePoint e adicionou um pequeno frame na thread chamado origin para me ajudar a rastrear sua origem. Assim que foi observado um grande número de threads, ela imprimiu as informações no STDERR. Isso pode ser rastreado em /var/www/discourse/logs/unicorn.stderr.log
Assim que soube que 100 threads estavam vindo todas de um único ponto, ficou muito fácil isolar a causa raiz.
Percebi que não consigo mais usar dev.local como meu hostname no modo de desenvolvimento no Rails 6, então adicionei uma variável de ambiente para configurar essa lista de permissões:
obrigado pelo seu esforço em trazer o Rails 6 para o Discourse! Posso humildemente perguntar quando isso deve ser integrado ao Discourse? Ou já está na versão 2.4.0.beta? Estou apenas perguntando sobre a possibilidade de isso quebrar algum plugin que as pessoas tenham instalado em suas instâncias.