enfrentando os demônios da
programação moderna
Episódio I
O Diabo da Concorrência
| “In a concurrent world, imperative is the wrong default.”
Tim Sweeney, CEO da Epic Games
O que é concorrência?
O que é concorrência?
O que é concorrência?
Concorrência x Paralelismo
Concorrência x Paralelismo
*meramente ilustrativo, não é bem assim
Process e Thread
Race Condition
● Dependência de várias tasks de um dado em comum
● Não-determinístico
Race Condition 🏃🏾♀️
Race Condition 🏃🏾♀️
CRuby: Global Virtual Machine Lock (GVL)
Evitando Race Condition ✋🏾🏃🏾♀️
Evitando Race Condition ✋🏾🏃🏾♀️
Node.JS: Event Loop
Como evitar esses problemas?
● Boas práticas (encapsular o estado, etc)?
● Evitar concorrência?
● Trabalhar com forks de aplicação
● …?
Ruby
Javascript
E se a gente só não
compartilhasse estado?
E se a gente só não
compartilhasse estado?
Tipo, de verdade? 🤯
Episódio II
De Volta para o Futuro
| “Reject modernity; embrace tradition.”
Algum conservador no twitter
Erlang
● Quase 40 anos de existência
● Pensada para resolver problemas de alta disponibilidade em telecom:
○ Distribuição
○ Tolerância a Falhas
BEAM
● Máquina virtual do Erlang
● Modelo de runtime desenhado para resolver os problemas citados
Actor Model
(bem, mais ou menos…)
Processos: Erlang Actors
● Unidades vivas e encapsuladas (como Processos do SO)
● Tudo é um Processo
● Se comunicam por meio de mensagens
● Não compartilham memória (!!!!)
● São muito leves (rodando em uma máquina comum pode chegar a milhões de processos)!
● Caso não consigam fazer o que precisam, eles morrem 💣
Actors
Mensagens de processos e Mailboxes ✉
● Mensagens podem ser qualquer coisa (um inteiro, um `map` ou até uma função)
● São não-bloqueantes
● Sabendo o id do processo (ou o nome dele), é possível enviar mensagens para qualquer um
● O processo destinatário nem precisa estar na mesma máquina que o remetente (!)
Coding Time! 💻
Se um processo der erro?
Podemos supervisionar processos!
Coding Time! 💻
Então, se processos são...
● Atômicos
● Se comunicam por mensagens
● Não compartilham estado
Então, se processos são...
● Atômicos
● Se comunicam por mensagens
● Não compartilham estado
Quer dizer que podemos fazer um
código concorrente de verdade? 🤔
SIM!
Não só concorrente,
mas paralelo também!
Um processo pode ocupar uma
thread indefinidamente?
Não. Isso é chamado de preemptive
scheduling
“o que linguagens fazem por segurança
de memória (como GC), Elixir também
faz por segurança de concorrência”
.
— Nathan Long em Elixir is Safe
Na prática,
quando vou usar isso?
Na prática,
quando vou usar isso?
Bem, não todo dia…
Na prática,
quando vou usar isso?
Bem, não todo dia…
Mas…
Em Elixir/Erlang, tudo é processo
Teste de websockets. Conexões simultâneas
Inclusive conexões com o servidor, por exemplo :)
E o ?
Concorrência em Go: CSP, Channels e Goroutines
Sender(s) Receiver(s)
Características
● Implementação em semáforos
● Arquitetura de threads parecida com a do Erlang
● Co-operative scheduling
● Goroutines são opcionais da linguagem
● Simples de implementar: `go func()`
Possíveis problemas
● Co-operative scheduling == block?
● Estado compartilhado ainda é possível
● Não há comunicação entre nodes
● Comunicação em channels não é 100% async
● Goroutines não se conhecem
Go e erlang possuem focos diferentes
● Golang:
○ Rápido deploy e execução
○ Fácil adoção
● Erlang/Elixir:
○ Tolerância a falhas
○ Distribuição
Em Go, concorrência é um detalhe de design;
em Erlang, é o ponto central da arquitetura
.
Finalizando...
Erlang e Beam: concorrência + resiliência by design
● Processos isolados e Actor Model*
● Preemptive Scheduling
● Árvore de Supervisão
● OTP
● Funcional
Pera, funcional?! 😥
Continua...
os alquimistas estão chegando 🤔
Referências
- Exploring Ruby’s Multi-threaded Weirdness (21/03/2021)
- Introdução ao Node.js (Single-Thread, Event-Loop e mercado) (19/03/2021)
- Frequently Asked Questions about Erlang (21/03/2021)
- JURIC, Sasa. Elixir in Action, 2019
- Erlang Scheduler Details and Why It Matters (21/03/2021)
- Who Supervises The Supervisors? (22/03/2021)
- Elixir is Safe (07/04/2021)
- Websocket Shootout: Clojure, C++, Elixir, Go, NodeJS, and Ruby (22/03/2021)
- COSTA, Gabriel et al. Escalabilidade de sistemas web em diferentes arquiteturas. TCC. 2020. (22/03/2021)
- Effective Go - The Go Programming Language (04/04/2021)
- Go vs Elixir: A concurrency comparison (03/04/2021)

Concorrência e Paralelismo em Elixir (e outras linguagens)

  • 1.
    enfrentando os demôniosda programação moderna
  • 2.
    Episódio I O Diaboda Concorrência | “In a concurrent world, imperative is the wrong default.” Tim Sweeney, CEO da Epic Games
  • 3.
    O que éconcorrência?
  • 4.
    O que éconcorrência?
  • 5.
    O que éconcorrência?
  • 6.
  • 7.
  • 8.
    *meramente ilustrativo, nãoé bem assim Process e Thread
  • 9.
  • 10.
    ● Dependência devárias tasks de um dado em comum ● Não-determinístico Race Condition 🏃🏾♀️
  • 11.
  • 12.
    CRuby: Global VirtualMachine Lock (GVL) Evitando Race Condition ✋🏾🏃🏾♀️
  • 13.
    Evitando Race Condition✋🏾🏃🏾♀️ Node.JS: Event Loop
  • 14.
    Como evitar essesproblemas? ● Boas práticas (encapsular o estado, etc)? ● Evitar concorrência? ● Trabalhar com forks de aplicação ● …?
  • 15.
  • 16.
    E se agente só não compartilhasse estado?
  • 17.
    E se agente só não compartilhasse estado? Tipo, de verdade? 🤯
  • 18.
    Episódio II De Voltapara o Futuro | “Reject modernity; embrace tradition.” Algum conservador no twitter
  • 19.
    Erlang ● Quase 40anos de existência ● Pensada para resolver problemas de alta disponibilidade em telecom: ○ Distribuição ○ Tolerância a Falhas BEAM ● Máquina virtual do Erlang ● Modelo de runtime desenhado para resolver os problemas citados
  • 20.
  • 21.
    Processos: Erlang Actors ●Unidades vivas e encapsuladas (como Processos do SO) ● Tudo é um Processo ● Se comunicam por meio de mensagens ● Não compartilham memória (!!!!) ● São muito leves (rodando em uma máquina comum pode chegar a milhões de processos)! ● Caso não consigam fazer o que precisam, eles morrem 💣
  • 22.
  • 23.
    Mensagens de processose Mailboxes ✉ ● Mensagens podem ser qualquer coisa (um inteiro, um `map` ou até uma função) ● São não-bloqueantes ● Sabendo o id do processo (ou o nome dele), é possível enviar mensagens para qualquer um ● O processo destinatário nem precisa estar na mesma máquina que o remetente (!)
  • 24.
  • 25.
    Se um processoder erro? Podemos supervisionar processos!
  • 26.
  • 27.
    Então, se processossão... ● Atômicos ● Se comunicam por mensagens ● Não compartilham estado
  • 28.
    Então, se processossão... ● Atômicos ● Se comunicam por mensagens ● Não compartilham estado Quer dizer que podemos fazer um código concorrente de verdade? 🤔
  • 29.
  • 31.
    Um processo podeocupar uma thread indefinidamente? Não. Isso é chamado de preemptive scheduling
  • 32.
    “o que linguagensfazem por segurança de memória (como GC), Elixir também faz por segurança de concorrência” . — Nathan Long em Elixir is Safe
  • 33.
  • 34.
    Na prática, quando vouusar isso? Bem, não todo dia…
  • 35.
    Na prática, quando vouusar isso? Bem, não todo dia… Mas…
  • 36.
    Em Elixir/Erlang, tudoé processo Teste de websockets. Conexões simultâneas Inclusive conexões com o servidor, por exemplo :)
  • 37.
  • 38.
    Concorrência em Go:CSP, Channels e Goroutines Sender(s) Receiver(s)
  • 39.
    Características ● Implementação emsemáforos ● Arquitetura de threads parecida com a do Erlang ● Co-operative scheduling ● Goroutines são opcionais da linguagem ● Simples de implementar: `go func()`
  • 40.
    Possíveis problemas ● Co-operativescheduling == block? ● Estado compartilhado ainda é possível ● Não há comunicação entre nodes ● Comunicação em channels não é 100% async ● Goroutines não se conhecem
  • 41.
    Go e erlangpossuem focos diferentes ● Golang: ○ Rápido deploy e execução ○ Fácil adoção ● Erlang/Elixir: ○ Tolerância a falhas ○ Distribuição Em Go, concorrência é um detalhe de design; em Erlang, é o ponto central da arquitetura .
  • 42.
  • 43.
    Erlang e Beam:concorrência + resiliência by design ● Processos isolados e Actor Model* ● Preemptive Scheduling ● Árvore de Supervisão ● OTP ● Funcional
  • 44.
  • 45.
  • 46.
    Referências - Exploring Ruby’sMulti-threaded Weirdness (21/03/2021) - Introdução ao Node.js (Single-Thread, Event-Loop e mercado) (19/03/2021) - Frequently Asked Questions about Erlang (21/03/2021) - JURIC, Sasa. Elixir in Action, 2019 - Erlang Scheduler Details and Why It Matters (21/03/2021) - Who Supervises The Supervisors? (22/03/2021) - Elixir is Safe (07/04/2021) - Websocket Shootout: Clojure, C++, Elixir, Go, NodeJS, and Ruby (22/03/2021) - COSTA, Gabriel et al. Escalabilidade de sistemas web em diferentes arquiteturas. TCC. 2020. (22/03/2021) - Effective Go - The Go Programming Language (04/04/2021) - Go vs Elixir: A concurrency comparison (03/04/2021)

Notas do Editor

  • #15 boas práticas: - É ótimo, mas um dev desavisado pode acabar fazendo 💩 evitar concorrência: Sacrifica performance forks: copia o estado da aplicação e roda paralelamente. custa muita memória e não abre espaço pra microcomunicação
  • #21 .