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

[RubyConfBR 2018] Event Driven Architecture for...

[RubyConfBR 2018] Event Driven Architecture for ruby applications

Já percebeu que nossa realidade é assíncrona? Nós enviamos uma mensagem (seja ela falada ou escrita) e esperamos que quem está nos ouvindo ou lendo receba a mensagem, entenda e nos responda apropriadamente. Além disso, muito do que acontece no mundo é visto por nós como “”coisas”” (ou eventos) que acontecem.
Por exemplo, ao pensarmos no processo de fechar um pedido em alguma loja online, o que geralmente acontece é: produtos são adicionados ou removidos até que o pedido seja fechado. Uma lista de produtos que foram fechados dentro de um pedido não reflete a realidade de como as coisas aconteceram, de que produtos foram adicionados e removidos até chegarmos ao ponto final do pedido fechado.
Essa talk vai mostrar o que isso tem a ver com código e como isso funciona no Ruby.

Talk apresentada na RubyConfBR 2018. Mais informações: https://eventos.locaweb.com.br/schedule/event-driven-architecture-for-ruby-applications/

Camila Campos

December 14, 2018
Tweet

More Decks by Camila Campos

Other Decks in Programming

Transcript

  1. @camposmilaa Camila Campos Dev @ Creditas Organizadora Rails Girls SP

    Organizadora Women Dev Summit @camposmilaa no Twitter
  2. @camposmilaa Plataforma online Empréstimo com garantia Juros baixos pra você

    <3 creditas.com.br vagas.creditas.com.br @CreditasBR
  3. @camposmilaa Junção de comunidades Incentivar mulheres em tech Palestras &

    Oficinas & Painéis womendevsummit.com fb.com/womendevsummit @WomenDevSummit
  4. @camposmilaa "OOP to me means only messaging, local retention and

    protection and hiding of state-process, and extreme late-binding of all things." Alan Kay
  5. @camposmilaa "The big idea is messaging [...] The key in

    making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be" Alan Kay
  6. @camposmilaa PRODUTO - nome - preço PEDIDO - data da

    compra CLIENTE - cpf - nome - data de nascimento
  7. @camposmilaa class Cachorro def latir 'au au' end end cachorro

    = Cachorro.new cachorro.latir # => 'au au'
  8. @camposmilaa class Cachorro def latir 'au au' end end cachorro

    = Cachorro.new # => 'au au' cachorro.latir
  9. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado
  10. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado nada acontece
  11. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado nada acontece
  12. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado nada acontece Sem receptor
  13. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado nada acontece Sem receptor nada acontece
  14. @camposmilaa Mensagens reais (correio) Mensagens no código (método) Conteúdo informação

    referências Sincronicidade assíncrona síncrona Conteúdo errado nada acontece Sem receptor nada acontece
  15. @camposmilaa Voltei de POA Fiquei nervouser Remarquei avaliação Fiquei mais

    nervouser Fui avaliada na firma 1. 2. 3. 4. 5. 6.
  16. @camposmilaa Voltei de POA Fiquei nervouser Remarquei avaliação Fiquei mais

    nervouser Fui avaliada na firma Meu Mac foi furtado 1. 2. 3. 4. 5. 6.
  17. @camposmilaa Solicitei um empréstimo Preenchi o cadastro Enviei documentos Meu

    crédito foi aprovado O empréstimo foi concedido 1. 2. 3. 4. 5.
  18. @camposmilaa Evento Solicitação Feita {nome: Joaquina, valor: 370.000} Documentos enviados

    {nome: Joaquina, documentos: [...]} Crédito Aprovado {nome: Joaquina}
  19. @camposmilaa Evento Solicitação Feita {nome: Joaquina, valor: 370.000} Documentos enviados

    {nome: Joaquina, documentos: [...]} Crédito Aprovado {nome: Joaquina} Crédito Concedido {nome: Joaquina}
  20. @camposmilaa Mensagens reais (correio) Eventos Conteúdo informação informação Sincronicidade assíncrona

    tanto faz Conteúdo errado nada acontece nada acontece Sem receptor nada acontece
  21. @camposmilaa Mensagens reais (correio) Eventos Conteúdo informação informação Sincronicidade assíncrona

    tanto faz Conteúdo errado nada acontece nada acontece Sem receptor nada acontece nada acontece
  22. @camposmilaa Event Sourcing Evento Solicitação Feita {nome: Joaquina, valor: 370.000}

    Crédito Aprovado {nome: Joaquina} Crédito Concedido {nome: Joaquina}
  23. @camposmilaa Pedido criado Item adicionado Item removido Item removido Item

    adicionado Item adicionado Pedido criado Item adicionado
  24. @camposmilaa Pedido criado Item adicionado Item adicionado Item removido Item

    adicionado Item removido Item adicionado Item adicionado Pedido criado Item adicionado
  25. @camposmilaa Pedido criado Item adicionado Item adicionado Item removido Endereço

    informado Endereço informado Item adicionado Item removido Item adicionado Item adicionado Pedido criado Item adicionado
  26. @camposmilaa CQRS Solicitar crédito Command Model Query Model Ver crédito

    Escrita Leitura Banco de escrita Banco de leitura
  27. @camposmilaa CQRS + Event Sourcing Event Sourcing (escrita) Relacional (leitura)

    evento 1, id: 2 evento 2, id: 1 evento 1, id: 1 id: 1, estado 2 id: 2, estado 1
  28. @camposmilaa Endereço informado Item adicionado Item removido Item adicionado Item

    adicionado Pedido criado Pedido Items (n) Endereço de entrega
  29. @camposmilaa Endereço informado Item adicionado Item removido Item adicionado Item

    adicionado Pedido criado Query Pedido Items (n) Endereço de entrega
  30. @camposmilaa Producer Consumer Kafka Producer Producer Consumer Consumer Tópico 1

    Tópico 2 Partição 1 Partição 2 Partição 1 Partição 2
  31. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  32. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  33. @camposmilaa class CommandConsumer < ::Karafka::BaseConsumer def consume command_name = params.dig('metadata',

    'name') use_case = use_case_from(command_name) use_case.execute(command_from(params)) end def use_case_from(command_name) # ... def command_from(message) # ... end
  34. @camposmilaa class CriarCaixaCommand < ::Dry::Struct attribute :fruta, Types::String attribute :quantidade,

    Types::Integer end class CriarCaixaUseCase def execute(command) caixa = Caixa.new(command.to_h) repository.save(caixa) end end
  35. @camposmilaa class CriarCaixaCommand < ::Dry::Struct attribute :fruta, Types::String attribute :quantidade,

    Types::Integer end class CriarCaixaUseCase def execute(command) caixa = Caixa.new(command.to_h) repository.save(caixa) end end
  36. @camposmilaa def caixa_criada_handler(evento) fruta = fruta_pelo_nome(evento.fruta) frutas << fruta.new(evento.quantidade) end

    def apply_changes(event) pending_events << event event_handlers[event.class].call(event) end end
  37. @camposmilaa def caixa_criada_handler(evento) fruta = fruta_pelo_nome(evento.fruta) frutas << fruta.new(evento.quantidade) end

    def apply_changes(event) pending_events << event event_handlers[event.class].call(event) end end
  38. @camposmilaa class CaixaRepository def save(caixa) eventos = caixa.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  39. @camposmilaa class CaixaRepository def save(caixa) eventos = caixa.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  40. @camposmilaa class CaixaRepository def save(caixa) eventos = caixa.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  41. @camposmilaa class CaixaRepository def save(caixa) eventos = caixa.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end end end
  42. @camposmilaa class CaixaRepository def save(caixa) eventos = caixa.pending_events # limpar

    lista de eventos pendentes eventos.each do |evento| events_table.insert( event: JSON.dump(evento.to_h)) end EstadoAtualDaCaixa.new.save(caixa) end end
  43. @camposmilaa Não é complicada 1. 2. 3. 4. 5. 6.

    Event Driven Architecture 1. 2. 3. 4. 5. 6.
  44. @camposmilaa Não é complicada Reflete a realidade 1. 2. 3.

    4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  45. @camposmilaa Não é complicada Reflete a realidade Auditoria de graça

    1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  46. @camposmilaa Não é complicada Reflete a realidade Auditoria de graça

    Serviços autônomos 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  47. @camposmilaa Não é complicada Reflete a realidade Auditoria de graça

    Serviços autônomos Escalável 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  48. @camposmilaa Não é complicada Reflete a realidade Auditoria de graça

    Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  49. @camposmilaa Assincronia Não é complicada Reflete a realidade Auditoria de

    graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  50. @camposmilaa Assincronia Consistência Eventual Não é complicada Reflete a realidade

    Auditoria de graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  51. @camposmilaa Assincronia Consistência Eventual Correções por eventos Não é complicada

    Reflete a realidade Auditoria de graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  52. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Não

    é complicada Reflete a realidade Auditoria de graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  53. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Replay

    tenso Não é complicada Reflete a realidade Auditoria de graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.
  54. @camposmilaa Assincronia Consistência Eventual Correções por eventos Demanda projeções Replay

    tenso Overengineering Não é complicada Reflete a realidade Auditoria de graça Serviços autônomos Escalável Análises mais complexas 1. 2. 3. 4. 5. 6. Event Driven Architecture 1. 2. 3. 4. 5. 6.