Princípios de Concorrência em Ruby e Além

Post on 03-Aug-2015

55 views 2 download

Transcript of Princípios de Concorrência em Ruby e Além

Princípios de Concorrência em Ruby

Renan Ranelli (Milhouse)

Agenda

➢ O que é concorrência ?➢ Pra quê escrever código concorrente ?➢ (Breve) Explicação dos diferentes modelos de concorrência➢ Por que escrever código concorrente é dificil ?➢ O que é o tão odiado GIL➢ Abstrações úteis que facilitam sua vida multithreaded➢ Exemplo de como usamos isso tudo em uma app real &

lições aprendidas

O que é concorrência?

➢Concorrência, assincronia e paralelismo são coisas relacionadas mas que muita gente as confunde.

➢ “Concurrency is when two tasks can start, run, and complete in overlapping time periods. It doesn’t necessarily mean they’ll ever both be running at the same instant. E.g. Multitasking in a single core machine”

➢ “Parallelism is when tasks literally run at the same time, e.g. on a multicore processor or SIMD instructions”

- Sun’s Multithreaded programming guide

O que é concorrência?

➢ Assincronia significa que o resultado de uma computação não esta disponível imediatamente após a avaliação.

➢ Significa que a maquina pode fazer outras coisas enquanto espera essa computação terminar e eventualmente no futuro fazer uso do resultado da mesma

Pra quê escrever código concorrente

➢ Concorrência possibilita assincronia e paralelismo➢ Libera o CPU para fazer outras coisas enquanto

espera por IO (http, banco, rede, disco, etc.) oferece mais performance. E.g. você poderá servir os requests de 30 usuários ao mesmo tempo ao invés de 1.

Diferentes modelos de concorrência

➢ Multiprocesses (resque, unicorn)➢ Multithreading (sidekiq)➢ Fibers (Ruby tem fibers!)➢ Corroutines ➢ Actors (Celluloid)➢ Outras bruxarias que eu não manjo(process calculi)

Multithreading

➢ Threads, assim como processos, são coisas oferecidas pelo SO.

➢ Mutexes ~➢ Deadlocks ~➢ Thread#join ~➢ Comportamento diferente com exceptions (e.g.

streaming do log no package-installer)

Multithreading

Multithreading

Pausa para o GIL

Pausa para o GIL

Pausa para o GIL

➢ O GIL (Global Interpreter Lock) impede que código ruby rode em paralelo.

➢ A unica ocasião em que é seguro para o GIL deixar coisas acontecerem em paralelo é com IO.

➢ Se sua vida é IO-bound, isso é o que importa.

Pausa para o GIL

Pausa para o GIL

Pausa para o GIL

Multithreading

➢ Considere que os jobs no sidekiq são unicos

Tem algum ruim nessa implementação ??➢

Multithreading – Evite Thread.new

➢ É uma boa idéia não usar threads diretamente.

➢ Existem várias abstrações melhores e mais seguras para expressar a task que você tem em mãos.

➢ Uma referência excelente é a lib do java java.util.concurrent. No mundo Ruby existe a gem concurrent-ruby que implementa parte do java.util.concurrent.

Multithreading – Abstrações

➢Abstrações úteis (todas disponíveis no concurrent-ruby):➢ IVars➢ Futures➢ Promises➢ Thread Pools➢ Channels➢ Software Transactional Memory (STM)➢ Agents

Multithreading – Abstrações

➢ IVars

Multithreading – Abstrações

➢ Futures

Feature:

As a highly responsive Ruby application

I want long-running tasks on a separate thread

So I can perform other tasks without waiting

Multithreading – Abstrações

➢ Futures

Multithreading – Abstrações

➢ Implementação porca

Multithreading – Abstrações

➢ Promises➢ Tipo Futures (só que Monads ;D)

➢ Pros Haskellistas: (then) = >==

Multithreading – Abstrações

➢Thread pools➢ Worke-horse dos executors.

Multithreading – Abstrações

Caso de uso - Hodor

Caso de uso - Hodor

Novo sistema

Old database

Caso de uso - Hodor

Caso de uso - Hodor

Caso de uso - Hodor

Caso de uso - Hodor

➢ Dahora! Tudo funcionava....

➢ Mas ai resolvemos medir:

Tempo atualizando status dos eventos na “fila”

Tempo fazendo o processamento dos eventos

Pareceu Fácil né ???

Foi nada.

Lições aprendidas

➢ PELO AMOR DE DEUS NÃO USA `Timeout::timeout` !!1!!1!!um!!onze!

Lições aprendidas

➢ Cuidado com o connection pool do ActiveRecord (Principalmente se for Rails < 4)

Lições aprendidas

➢ Por favor, atualizem as versões dos drivers de banco. TinyTds ~ 0.5 tinha zilhares de issues relacionadas a multi-threading.

Lições aprendidas

➢ Metricas são muito mais legais que logs

➢ http://webleela.service.ita.consul.locaweb.com.br/index.html#/dashboard/db/heisenberghodor

Lições aprendidas

➢ Converse (e ajude!) com a galera que desenvolve as gems

➢Figura pare pense ?➢

➢Para evitar problemas como o da foto do mimi triste:➢ 1. Não use concorrência➢ 2. Se for usar, não compartilhe nada. Não decida usar

antes de MEDIR e ter certeza que você realmente precisa.

➢ 3. Se tiver que compartilhar, tomar muito cuidado pra sincronizar o acesso