Uma linha de configuração

Prévia grátis 4 min de leitura

A troca automática de papéis é ligada por uma única linha, e o tamanho dessa linha engana: ela muda com qual banco cada requisição da aplicação conversa.

config.active_record.database_selector = { delay: 2.seconds }

Esta aplicação não define essa linha, e o curso de nível Sênior "Arquitetura de banco de dados: réplicas" explicou por quê: não existe réplica para onde trocar. Mesmo assim, vale entender a maquinaria, porque no momento em que uma réplica existir essa linha é o caminho mais curto para usá-la, e o caminho mais curto nem sempre é o mais seguro.

O que ela insere

A linha instala um middleware Rack que envolve cada requisição. Todo o trabalho dele, tirado do ActiveRecord::Middleware::DatabaseSelector:

response = if resolver.reading_request?(request)
  resolver.read(&blk)
else
  resolver.write(&blk)
end
resolver.update_context(response)

São três peças móveis, e vale nomeá-las separadamente, porque cada uma pode ser trocada sozinha.

O contexto lembra alguma coisa sobre essa pessoa entre uma requisição e outra. Por padrão, ele é a sessão.

O resolvedor decide, a partir da requisição e do contexto, se essa requisição lê da réplica.

O middleware liga os dois e envolve a requisição no papel escolhido.

flowchart TB
  R["uma requisição chega"] --> M["middleware DatabaseSelector"]
  M --> C["contexto: o que lembramos desta sessão?"]
  M --> S["resolvedor: leitura ou escrita? réplica ou primário?"]
  C --> S
  S --> W["a requisição roda dentro de connected_to(role: ...)"]
  W --> U["update_context: registra se esta requisição escreveu"]

A decisão inteira são duas perguntas

Esta é uma requisição de leitura? O verbo HTTP responde, e a lição 2 trata disso.

Esta sessão escreveu há pouco? Um timestamp na sessão responde, e a lição 3 trata disso.

Essa é a política inteira. Não há inspeção de query, nem noção de tabela, nem configuração por modelo. É uma regra prática sobre HTTP aplicada do mesmo jeito a todo endpoint da aplicação, inclusive aos endpoints escritos depois que ela foi ligada.

Por que ela é opcional

O Rails entrega isso desligado, e essa é uma afirmação proposital: o framework não vai supor que as suas requisições GET podem ser servidas por uma réplica, porque ele não tem como saber.

Compare com a forma explícita daquele curso:

ActiveRecord::Base.connected_to(role: :reading) do
  SomeReport.generate
end

Esse bloco é uma afirmação sobre um código que você está vendo. O middleware é uma afirmação sobre um código que você ainda não leu, e a diferença entre as duas coisas é o assunto deste curso.

O que você configura ao definir a linha

O delay é o único botão, e ele é uma duração:

{ delay: 2.seconds }

É por quanto tempo uma sessão fica presa ao primário depois de escrever. Se for baixo demais, as pessoas leem dados desatualizados depois de salvar. Se for alto demais, a réplica fica sem uso para quem acabou de enviar um formulário.

Repare no que você não consegue configurar aqui: quais requisições são leituras. O resolvedor fixa isso, e mudar exige fornecer o seu próprio. A lição 6 trata disso, e essa costuma ser a resposta certa com mais frequência do que o botão delay dá a entender.

Pontos-chave

  • config.active_record.database_selector = { delay: 2.seconds } instala um middleware que envolve cada requisição.
  • São três peças trocáveis: um contexto que lembra, um resolvedor que decide e um middleware que liga os dois.
  • A política são duas perguntas: esta é uma requisição de leitura, e esta sessão escreveu há pouco?
  • Ela vem desligada porque o Rails não tem como saber se as suas requisições GET são seguras numa réplica.
  • O delay é o único botão. Quais requisições contam como leitura fica fixo, a menos que você forneça o seu próprio resolvedor.
Aula 1 de 7 · grátis

Continue com a aula 2

O verbo é o sinal

O resolvedor trata GET e HEAD como leituras, então é preciso auditar antes as requisições GET que escrevem.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...