Na última semana, me aventurei no desenvolvimento de software pesquisando o conceito de atores virtuais. Acabei pesquisando dois frameworks diferentes: Dapr e Orleans.
Ambos são projetos muito concisos com muitos casos de uso interessantes. Ambos usam a ideia de atores "virtuais". Um ator virtual é uma unidade de estado e lógica que:
- Pode ser identificado de forma única pelo DI
- É de rosca única
- Pode ser em memória ou persistente – seu ciclo de vida é gerenciado pelo framework
Gosto muito da ideia de atores virtuais e os acho muito úteis na minha exploração de como construir ferramentas escaláveis e confiáveis para lidar com fluxos de trabalho complexos. Se cada tarefa for um participante virtual de thread única, o problema da condição de corrida desaparece.
Como Orleans e Dapr são projetos da Microsoft, imagino um dia em um confronto no estilo Western Story na cafeteria da Microsoft.
Orleães
Comecei com Orleans porque já estava no meu radar há um tempo, depois de ver alguns vídeos sobre isso no YouTube. Começou muito mal porque achei que usaria a versão 4.x de todos os pacotes NuGet deles. No entanto, absolutamente nenhuma documentação deles funciona com o pacote 4.x. Acabei usando a versão 3.6.2.
Grãos / Estado / Temporizadores
Criar um grão que acompanhe seu próprio estado e execute ações é muito simples. Consegui até acompanhar a documentação de persistência de grãos e criar minha própria implementação do IGrainStorage no CosmosDB (SQL API).
Lembretes
Lembretes também são fáceis de configurar. Até tentar configurar persistência no mundo real para eles. Neste ponto da minha pesquisa, estou tentando manter tudo arrumado e armazenar tudo no ComsosDB. Infelizmente, não consigo fazer o pacote de persistência de lembretes de Orleans funcionar de jeito nenhum. Acabei tendo que mudar para o pacote AzureStorage. Agora meus dados estão metade na conta da API SQL e metade na conta da API da tabela.
Fluxos
Foi aí que eu não tive sucesso. Em Orleans, os fluxos são identificados por um GUID e um namespace opcional. Tenho certeza de que há um bom motivo para os streams precisarem ser identificados por um GUID, mas uau, isso é impraticável.
Estou muito frustrado com streams porque consegui criá-los facilmente, mas quando paro e reinicio meu projeto e desencadeio um novo evento, tudo trava.
Em seguida, vem uma informação muito valiosa, pois levei 8 horas para fazer engenharia reversa do código de Orleans para descobrir:
Quando um grão é um assinante de stream, ele deve chamar ResumeAsync no handle de assinatura em seu método OnActivateAsync, ou você travará com um erro não reconhecido.
Também tive o problema da mesma assinatura ser duplicada, então usei o código para apagar todas as assinaturas do grão e depois o recriei:
Outras Dicas / Pegadinhas de Orleans
Streams funciona bem com os Hubs de Eventos do Azure (via AddEventHubStreams).
Não use / ou outros caracteres especiais no nome Grain da API SQL do CosmosDB!
Conclusão de Orleans
Gosto de Orleans e acho que tem potencial. No entanto, a curva de aprendizado é muito íngreme. Por causa da minha longa luta com streaming, não tenho tempo para estudar como funcionam clusters/implantações.
Dapr
Encontrei Dapr procurando alternativas a Orleans. É um pouco estranho que também seja um projeto patrocinado pela Microsoft. Talvez estejam aqui para adotar uma abordagem de sobrevivência do mais apto. Se sim, acho que Dapr será um sobrevivente.
Primeiro, o design baseado em REST/gRPC da Dapr permite que atores sejam implementados usando qualquer linguagem de programação. Também achei trividal rodar tudo (participantes, status, temporizadores, lembretes, eventos) em uma única instância do Rede. Além disso, levei cerca de um terço do tempo para começar a usar Dapr. Esse tempo de início tão rápido se deve à excelente documentação da Dapr.
Atores / Temporizadores / Lembretes
Acabei de dizer que a documentação da Dapr é ótima? Bem, está em todo lugar, exceto em exemplos de JavaScript. Passo a maior parte do tempo no Dapr, tentando descobrir como chamar métodos aos atores. O código para o exemplo Dapr Javascript é o seguinte:
Isso está claramente desatualizado. Tive que gastar muito tempo para conduzir essas três linhas pela exploração de testes/código de exemplo do Dapr
Os exemplos de código para obtenção/definição de estado têm problemas semelhantes, então criei uma edição no GitHub para eles.
Exceto por esses pequenos problemas, preparar os atores é moleza.
Configurar temporizadores e lembretes para meu lançamento também é muito fácil.
Estado
Consegui configurar o Dapr para persistir com o Postgres muito facilmente.
Uma coisa que percebi é que pode haver problemas de escalabilidade na forma como os lembretes são armazenados. O Dapr armazena todos os alertas de um tipo específico de participante em um único array JSON. O que acontece se alguém tiver muitos lembretes?
Outras Dicas / Pegadinhas de Dapr
Uma coisa que notei ao navegar pelo código do SDK JavaScript é que não há muitos comentários na base de código. Isso torna quase impossível descobrir algo. Por exemplo, no método addOrUpdateState do gerenciador de estados, há um terceiro parâmetro chamado updateValueFactory. Se não houver comentários no código, é quase impossível saber para que serve o callback.
Também não tenho certeza do quanto gosto do comando "dapr init" tentando configurar e rodar um container Redis para mim. E se eu já tiver um contêiner Redis? E se eu quiser usar o postgres em vez disso? Não consigo encontrar documentação explicando como mudar o recurso DAPR Init.
Uma nota para quem estiver tendo dificuldades para usar o pubsub. Você deve usar "dapr run" para rodar tanto sua editora quanto seu assinante:
Para atores e pubsub, note que é importante usar o parâmetro --app-port para avisar o DAPR em qual porta seu serviço está rodando. Eventos pubsub e chamadas de atores são enviados para seu serviço pelo sidecar Dapr via chamadas HTTP, então ele precisa saber para onde enviá-los:
Testei um pequeno "cluster" autohospedado Dapr lançando minha instância de assinante do pubsub em duas máquinas diferentes da minha rede doméstica. Simplesmente funcionou!
Conclusão Dapr
Se você quer saber mais ideias sobre aplicações distribuídas ou atores virtuais, recomendo começar pelo Dapr. Orleans foi o pioneiro original, enquanto Dapr foi um reboot que levou as coisas a outro nível.
Link original:O login do hiperlink está visível.
|