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.

A8725b0691ad37a2554a71652d70831b?s=128

Marcos Castilho da Costa Matos

September 15, 2012
Tweet

Transcript

  1. CINEMA RUBY O modelo de Atores para aplicações concorrentes Sunday,

    September 16, 12
  2. apresentando MARCOS MATOS @ marcosccm Sunday, September 16, 12

  3. desenvolvedor na ThoughtWorks Sunday, September 16, 12

  4. “Como você lida com concorrência?” Sunday, September 16, 12

  5. Concorrência? Sunday, September 16, 12

  6. “Lidar com multiplas tarefas simultaneamente“ Sunday, September 16, 12

  7. concorrência paralelismo Sunday, September 16, 12

  8. “Méh, isso é coisa de programador Java!” (ou outros seres

    estranhos) Sunday, September 16, 12
  9. Sunday, September 16, 12

  10. “Lembra do tempo em que se comparava clock de cpu?

    “ Sunday, September 16, 12
  11. Isso acabou! (há muito tempo) Sunday, September 16, 12

  12. Por que nos esforçamos para ignorar concorrência? Sunday, September 16,

    12
  13. Sunday, September 16, 12

  14. Concorrência nos lembra de Threads Sunday, September 16, 12

  15. Ninguém gosta de Threads Sunday, September 16, 12

  16. Racing Conditions! Deadlocks! Starvation! Sunday, September 16, 12

  17. 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
  18. Sunday, September 16, 12

  19. Threads são malignas Sunday, September 16, 12

  20. Mas espere! Sunday, September 16, 12

  21. o problema não é bem as threads Sunday, September 16,

    12
  22. e sim... Sunday, September 16, 12

  23. Mutabilidade compartilhada Sunday, September 16, 12

  24. “Mutable shared state is the root of all evil” Sunday,

    September 16, 12
  25. Problemas de concorrência se resolvem controlando mutabilidade Sunday, September 16,

    12
  26. Existem diversas estratégias Sunday, September 16, 12

  27. STM Atomic Operations Pure Functions Channels Sunday, September 16, 12

  28. e também... Sunday, September 16, 12

  29. ATORES Sunday, September 16, 12

  30. Sunday, September 16, 12

  31. Ao invés de Threads concorrentes... Sunday, September 16, 12

  32. Objetos Concorrentes! Sunday, September 16, 12

  33. ATOR ATOR ATOR Text mensagen Estado mensagen mensagen Sunday, September

    16, 12
  34. mensagens assíncronas ATOR mailbox estado mutável Sunday, September 16, 12

  35. Comunicação inteiramente por Mensagens assíncronas Sunday, September 16, 12

  36. Nenhum estado compartilhado Sunday, September 16, 12

  37. nenhum estado! Sunday, September 16, 12

  38. Nascidos juntos com a Orientação a Objectos Sunday, September 16,

    12
  39. Sunday, September 16, 12

  40. 1973 - Actors 1972 - SmallTalk Sunday, September 16, 12

  41. “OOP means only messaging, local retention and protection and hiding

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

    of state processing” Sunday, September 16, 12
  43. Atores OO antes de alguém ouvir falar sobre isso Sunday,

    September 16, 12
  44. Apesar disso, foram popularizados por Erlang e Scala Sunday, September

    16, 12
  45. mas... Sunday, September 16, 12

  46. e o Ruby? Sunday, September 16, 12

  47. bem... Sunday, September 16, 12

  48. Nós temos o GIL (Python tambem tem...) Sunday, September 16,

    12
  49. GLOBAL INTERPRETER LOCK Sunday, September 16, 12

  50. thread thread thread thread thread GIL RUBY Ruby VM Sistema

    Operacional Sunday, September 16, 12
  51. Ruby não escala! Não tem paralelismo! Bando de Troll! Sunday,

    September 16, 12
  52. sim, mas não Sunday, September 16, 12

  53. Historicamente, rubistas sempre preferiam process e forks Sunday, September 16,

    12
  54. recente ênfase em Concorrência, principalmente por implementações alternativas Sunday, September

    16, 12
  55. Rubinius e JRuby não tem mais o lendário GIL son

    Sunday, September 16, 12
  56. Diversas implementações de Atores em ruby Sunday, September 16, 12

  57. Celluloid Actors.rb Girl-Friday Sunday, September 16, 12

  58. Celluloid Sunday, September 16, 12

  59. Concorrência + Orientação a objetos Sunday, September 16, 12

  60. class Ator include Celluloid def trabalho_duro sleep 100 !!!# Computação

    lenta 'trabalho feito!' end end Sunday, September 16, 12
  61. má que! Sunday, September 16, 12

  62. Cade os mailboxes e respostas assíncronas!? Sunday, September 16, 12

  63. Sunday, September 16, 12

  64. 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
  65. O segredo é o uso de Proxies e Futures Sunday,

    September 16, 12
  66. Chamadas Normais outro Proxy mailbox ATOR mailbox Sunday, September 16,

    12
  67. Chamadas Assíncronas outro Proxy mailbox ATOR mailbox Nil Sunday, September

    16, 12
  68. Chamadas com Future outro ATOR mailbox Proxy Future Sunday, September

    16, 12
  69. tudo isso se baseia em fibers e threads Sunday, September

    16, 12
  70. mais um exemplo Sunday, September 16, 12

  71. 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
  72. 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
  73. e tem mais! Sunday, September 16, 12

  74. Grupos de atores podem ser criados facilmente Sunday, September 16,

    12
  75. pool = MeuAtor.pool(:size => 50) # delega trabalho para um

    membro # da pool pool.async.trabalho_duro Sunday, September 16, 12
  76. E se algum ator cair? Sunday, September 16, 12

  77. Ferramentas de tolêracia a falhas roubadas do Erlang Sunday, September

    16, 12
  78. Linking Supervisor Supervisor Groups Sunday, September 16, 12

  79. outra coisa interessante sobre atores... Sunday, September 16, 12

  80. eles não precisam ficar no mesmo lugar! Sunday, September 16,

    12
  81. DCell Atores distribuidos Sunday, September 16, 12

  82. legais esses atores, mas, será que faz alguma diferença? Sunday,

    September 16, 12
  83. Sim! Sunday, September 16, 12

  84. 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
  85. Concluindo Sunday, September 16, 12

  86. Concorrência é Tenso Sunday, September 16, 12

  87. mas ignorá- la não adianta Sunday, September 16, 12

  88. os problemas tem solução Sunday, September 16, 12

  89. Rubistas não estão sozinhos nisso Sunday, September 16, 12

  90. Saia da Caixa! Sunday, September 16, 12

  91. The End Sunday, September 16, 12