operações de carga com ruby

mine

À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.