operações de carga com ruby
Às vezes temos que fazer operações de carga / extração em bases de dados.
Como não podia deixar de ser, muitas vezes esse banco de dados é um banco totalmente legado, entupido de chaves compostas, e pra piorar a situação, concorrido entre diversas aplicações da empresa.
Como extrair dados sem impactar a performance do banco de origem?
Antes que você me fale que existem ferramentas de ETL, meu objetivo é mostrar alternativas, certo? Então, vamos lá.
Uma abordagem simples e interessante é uma implementação do modelo de produtor / consumidor, utilizando uma fila e duas threads:
require 'thread'
fila = Queue.new
TAMANHO_TOTAL = 100
produtor = Thread.new do
# extrai os dados de algum lugar
(1..TAMANHO_TOTAL).each do |i|
# simulando trabalho
sleep rand(1)
fila << i
end
end
consumidor = Thread.new do
# array de trabalho
buffer = []
(1..TAMANHO_TOTAL).each do
buffer << fila.pop
# vamos processar de 4 em 4 items
if buffer.size >= 4 or not produtor.alive?
# faz alguma coisa com as tarefas
puts buffer.inspect
# limpa a fila
buffer.clear
end
end
# faz alguma coisa com as tarefas que sobraram
puts buffer.inspect
buffer.clear
end
consumidor.join
Simples não? E você ainda ganha muito mais se executar esse mesmo código com jruby, graças ao suporte à threads da JVM.