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

Transcript

206 slides
  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.

More Decks by Camila Campos

Other Decks in Programming