Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cinema Ruby

Cinema Ruby

Todos sabemos que concorrência é uma coisa complicada. Threads! Racing Conditions! Bugs impossíveis de resolver! Mas não! Simples uso de threads não é a única forma de se obter concorrência. Esta palestra apresenta o modelo de atores e como aplicá-lo em Ruby. Com atores você pode aproveitar do poder dos computadores modernos, sem ter que apelar para mutexes e semaphores.

Marcos Castilho da Costa Matos

September 15, 2012
Tweet

More Decks by Marcos Castilho da Costa Matos

Other Decks in Programming

Transcript

  1. mutex = Mutex.new cv = ConditionVariable.new a = Thread.new {

    mutex.synchronize { sleep 200 cv.wait(mutex) sleep 100 } } b = Thread.new { mutex.synchronize { sleep 200 cv.signal sleep 200 } } a.join; b.join Sunday, September 16, 12
  2. “OOP means only messaging, local retention and protection and hiding

    of state processing” Alan Kay Sunday, September 16, 12
  3. “Actors means only messaging, local retention and protection and hiding

    of state processing” Sunday, September 16, 12
  4. class Ator include Celluloid def trabalho_duro sleep 100 !!!# Computação

    lenta 'trabalho feito!' end end Sunday, September 16, 12
  5. ator = Ator.new #chamada bloqueante normal ator.trabalho_duro #retorna nil ator.async.trabalho_duro

    #retorna um future ator.future.trabalho_duro Sunday, September 16, 12
  6. class FileProcessor include Celluloid def initialize(collector) @collector = collector end

    def process_file(path) if File.directory?(path) get_files(path).each do |file| ! @collector.mark_for_processing!(file) end else file_size = calculate_size(path) @collector.register_file_size!(file_size) end @collector.request_file!(Actor.current) end end Sunday, September 16, 12
  7. class SizeCollector include Celluloid def initialize #snip end def dispatch_file

    return unless has_files_to_visit? processor = @idleProcessors.shift file = @filesToProcess.shift processor.process_file!(file) end def mark_file_for_processing(file) @filesToProcess << file @pendingFilesToVisit += 1 dispatch_file end def request_file(processor) @idleProcessors << processor dispatch_file end # mais métodos Sunday, September 16, 12
  8. pool = MeuAtor.pool(:size => 50) # delega trabalho para um

    membro # da pool pool.async.trabalho_duro Sunday, September 16, 12
  9. O caso do Sidekiq “we replaced 12-15 EC2 medium instances

    running 4 delayed_job processes each with a single EC2 medium instance running 4 sidekiq workers with 25 concurrency each. The final tally is something like $2500 less per month in EC2 costs.” Sunday, September 16, 12