{"id":7439,"date":"2018-04-06T17:27:40","date_gmt":"2018-04-06T20:27:40","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=7439"},"modified":"2018-04-09T10:28:30","modified_gmt":"2018-04-09T13:28:30","slug":"elixir-processos-e-esse-tal-de-otp","status":"publish","type":"post","link":"http:\/\/blog.plataformatec.com.br\/2018\/04\/elixir-processos-e-esse-tal-de-otp\/","title":{"rendered":"Elixir, processos e esse tal de OTP"},"content":{"rendered":"

Uma das grandes caracter\u00edsticas da linguagem Elixir \u00e9 a maneira como ela lida com concorr\u00eancia, como isso traz benef\u00edcios no dia-a-dia e como isso agrega valor ao software final. <\/span><\/p>\n

Quando vamos estudar sobre concorr\u00eancia, uma das coisas que surgem durante esse aprendizado \u00e9 uma tal sigla que escutamos muito, chamada OTP.<\/span><\/p>\n

OTP<\/b><\/h3>\n

A sigla significa <\/span>Open Telecom Platform<\/span><\/i>, mas ningu\u00e9m a usa exclusivamente para telecom hoje em dia. No livro <\/span>Designing for Scalability with Erlang\/OTP<\/span><\/i> dos autores Francesco Cesarini e Steve Vinoski, eles definem OTP como tr\u00eas componentes principais que interagem entre si: o primeiro sendo o pr\u00f3prio Erlang, o segundo um <\/span>conjunto de bibliotecas<\/span><\/a> dispon\u00edveis com a <\/span>virtual machine<\/span><\/i> e o terceiro um conjunto de princ\u00edpios de design do sistemas.<\/span><\/p>\n

Por isso talvez voc\u00ea j\u00e1 tenha ouvido falar no termo <\/span>OTP compliant<\/span><\/i>, que quer dizer que a aplica\u00e7\u00e3o segue os princ\u00edpios de design de sistemas estabelecidos pelo Erlang\/OTP.<\/span><\/p>\n

Um dos itens desse conjunto de princ\u00edpios consiste na utiliza\u00e7\u00e3o de uma arquitetura de processos para resolver os problemas da sua aplica\u00e7\u00e3o.<\/span><\/p>\n

Processos<\/b><\/h3>\n

Quando falamos de processo em Elixir, estamos nos referindo aos processos da m\u00e1quina virtual do Erlang, e n\u00e3o aos processos do sistema operacional. Os processos da BEAM (m\u00e1quina virtual do Erlang) s\u00e3o muito mais leves e baratos do que aqueles \u00a0do sistema operacional, e rodam em todos os <\/span>cores<\/span><\/i> dispon\u00edveis na m\u00e1quina por serem mais leves, em m\u00e9dia 2k, portanto, podemos criar milhares deles em nossa aplica\u00e7\u00e3o.<\/span><\/p>\n

Eles s\u00e3o isolados uns dos outros e se comunicam atrav\u00e9s de mensagens, dessa maneira nos ajudam a dividir a carga de trabalho e a rodar coisas em paralelo.<\/span><\/p>\n

Por Elixir ser uma linguagem funcional, uma de suas caracter\u00edsticas \u00e9 a imutabilidade, o que nos ajuda a deixar o estado expl\u00edcito. Dessa maneira, quando separamos nosso c\u00f3digo em tarefas independentes que podem rodar concorrentemente, n\u00e3o precisamos nos preocupar em controlar seu estado utilizando mecanismos complexos para garantir isso, coisas como <\/span>mutex<\/span><\/a> e a utiliza\u00e7\u00e3o de <\/span>threads<\/span><\/a> n\u00e3o s\u00e3o mais necess\u00e1rias.<\/span><\/p>\n

Como processos funcionam em Elixir?<\/b><\/h3>\n

\u00c9 muito comum associarmos processos e a troca de mensagens existentes entre eles com o <\/span>modelo de atores para concorr\u00eancia<\/span><\/a>. Isso acontece porque cada processo em Elixir \u00e9 independente e totalmente isolado um do outro. Um processo pode guardar estado, mas isso n\u00e3o \u00e9 compartilhado e a \u00fanica maneira de compartilhar algo entre processos \u00e9 atrav\u00e9s do envio de mensagens.<\/span><\/p>\n

Cada processo possui uma mailbox<\/code> que, como o nome sugere, \u00e9 respons\u00e1vel por receber mensagens de outros processos. Vale dizer tamb\u00e9m que quando enviamos uma mensagem, tudo acontece assincronamente, dessa maneira n\u00e3o \u00a0bloqueamos o processamento aguardando por uma resposta.<\/span><\/p>\n

Uma maneira de pensarmos nisso \u00e9 imaginarmos processos como celulares que utilizam SMSs para troca de informa\u00e7\u00f5es. Cada celular tem um local para armazenar essas mensagens at\u00e9 que elas sejam tratadas e isso acontece de maneira independente e isolada.<\/span><\/p>\n

\"\"<\/p>\n

Vale mencionar tamb\u00e9m que podemos vincular um processo ao outro. Isso \u00e9 importante \u00a0porque \u00e9 com base nisso que podemos identificar falhas e tomar alguma a\u00e7\u00e3o para lidar com elas.<\/span><\/p>\n

Quando temos processos que monitoram outros processos, damos o nome de Supervisor<\/em>. Podemos ter v\u00e1rios deles em nossa aplica\u00e7\u00e3o e quando temos mais de um Supervisor<\/em> monitorando processos \u00e9 o que chamamos de \u00c1rvore de Supervis\u00e3o.
\n\"\"<\/span><\/p>\n

Isso \u00e9 muito importante porque \u00e9 atrav\u00e9s disso que obtemos a toler\u00e2ncia a falhas. Quando temos um problema com o nosso c\u00f3digo, o que n\u00e3o queremos \u00e9 que isso afete o usu\u00e1rio final. Atrav\u00e9s do monitoramento de processos podemos identificar quando algo inesperado acontece e assim tomar uma a\u00e7\u00e3o sobre isso, finalizando o processo com problema e iniciando-o novamente. \u00a0Assim, o processo volta ao seu estado inicial nos dando tempo para agir e resolver o problema que causou o erro.<\/span><\/p>\n

Como isso funciona para concorr\u00eancia?<\/b><\/h3>\n

Quando a BEAM inicia, ela tamb\u00e9m inicia uma thread chamada <\/span>Scheduler<\/span><\/i> que \u00e9 respons\u00e1vel por rodar cada processo concorrentemente na CPU.<\/span><\/p>\n

Para poder obter toda vantagem do hardware, a BEAM inicia um Scheduler<\/em> para cada core dispon\u00edvel, ou seja, um computador que possui quatro <\/span>cores<\/span><\/i>, vai ter quatro <\/span>schedulers<\/span><\/i>, cada um rodando v\u00e1rios processos concorrentemente.<\/span><\/p>\n

\"\"<\/p>\n

Processos s\u00e3o a base para o modelo de concorr\u00eancia que usamos em Elixir. Muitas das funcionalidades que precisamos ao utiliz\u00e1-los possuem alguma abstra\u00e7\u00e3o para nos ajudar, portanto, dessa maneira n\u00e3o precisamos nos preocupar com os detalhes de implementa\u00e7\u00e3o de fun\u00e7\u00f5es mais primitivas, como <\/span>spawn<\/span>, <\/span>send<\/span><\/em>\u00a0e\u00a0<\/span>receive<\/span>.<\/span><\/p>\n

Quando utilizamos essas fun\u00e7\u00f5es primitivas, precisamos nos preocupar com muito mais detalhes que s\u00e3o pass\u00edveis de erros para conseguirmos atingir nosso objetivo e deixar nosso c\u00f3digo <\/span>OTP compliant<\/span><\/i>. Normalmente, os desenvolvedores(as) n\u00e3o usam essas fun\u00e7\u00f5es, ao inv\u00e9s disso, usam abstra\u00e7\u00f5es como Task, GenServer<\/em> e Agent<\/em>. Mas isso j\u00e1 \u00e9 assunto para outro post.<\/span><\/p>\n

 <\/p>\n","protected":false},"excerpt":{"rendered":"

Uma das grandes caracter\u00edsticas da linguagem Elixir \u00e9 a maneira como ela lida com concorr\u00eancia, como isso traz benef\u00edcios no dia-a-dia e como isso agrega valor ao software final. Quando vamos estudar sobre concorr\u00eancia, uma das coisas que surgem durante esse aprendizado \u00e9 uma tal sigla que escutamos muito, chamada OTP. OTP A sigla significa … \u00bb<\/a><\/p>\n","protected":false},"author":67,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[3],"tags":[143,281],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/7439"}],"collection":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=7439"}],"version-history":[{"count":6,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/7439\/revisions"}],"predecessor-version":[{"id":7449,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/7439\/revisions\/7449"}],"wp:attachment":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=7439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=7439"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=7439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}