operações de carga com ruby


posted by qmx on 28 July 2010
http://farm1.static.flickr.com/122/308587800_c8d0417f1e.jpg

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