Paralelismo ao usar as Funções do Azure para atualizar um documento do DocumentDB

5

Estou escrevendo um aplicativo da web que permite que os usuários façam upload de listagens de imóveis. Parte do que isso faz é permitir que eles façam upload de fotos da propriedade que estão listando.

Estou usando uma abordagem de tipo de micro-serviço para que haja um serviço de mídia de propriedade que lide com todo o carregamento de mídia, consultando quais mídias estão disponíveis para cada propriedade, etc.

No entanto, como preciso pesquisar e exibir rapidamente uma página de propriedades sem chamar 7 ou 8 serviços, também mantenho uma coleção de propriedades do Azure DocumentDB, em que cada documento contém tudo sobre a propriedade específica necessária para oferecer suporte à pesquisa e à vinculação de a página de detalhes da propriedade.

Até aí tudo bem.

Optei por um padrão de fornecimento de eventos em que, quando uma nova foto era enviada, eu simplesmente criava um evento em um tópico do Barramento de Serviço do Azure. Houve uma assinatura para este tópico que foi um disparador para uma Função do Azure que carregaria o documento, atualizaria com os detalhes da imagem carregada e salvaria.

Funcionou - mas depois tenho um problema de paralelismo / simultaneidade pelo qual, se um usuário faz o upload de 10 imagens, ele cria 10 eventos no tópico. Com a natureza das Funções do Azure, pode gerar 10 processos simultaneamente, cada um entregando uma mensagem.

Como o DocumentDb do Azure não oferece suporte a atualizações parciais de documentos, a função do Azure executa estas etapas:

  • Carrega o documento
  • Adiciona um filho à coleção images
  • Salva o documento

Recentemente, observei que não recebo uma atualização confiável ao fazer upload de várias imagens. Talvez apenas 6 dos 10 apareçam no DocumentDb. Os logs da função mostram que todas as 10 execuções foram bem-sucedidas, então só posso assumir aqui que fui vítima delas executando em paralelo e uma atualização sobrescrevendo outra.

Para contornar isso, eu fiz isso para que o serviço de mídia não levante mais um evento, mas apenas atualiza o próprio DocumentDb. Mas eu não estou muito feliz com isso porque não é realmente sua responsabilidade em minha mente. Ele resolveu o problema por enquanto - mas eu gostei do evento-sourcing e das Funções do Azure atualizando o documento como um design melhor.

Existe alguma opção melhor para mim? Eu considerei que poderia adicionar um documento à coleção DocumentDb na função do Azure em vez de atualizar um "documento mestre", mas isso significaria mais trabalho na página de detalhes da propriedade para agregá-lo.

Eu perdi um truque?

    
por bgs264 04.03.2017 / 16:08
fonte

1 resposta

0

Assim, minha compreensão do Event Sourcing é que você recria seu objeto a partir de eventos salvos, em vez da tradicional desserialização do estado do objeto. Parece que você não está realmente fazendo isso.

Porque a ordem dos eventos é geralmente importante. Isso exige alguma forma de transação manual, na qual você atribui IDs de eventos sequenciais ou um número de versão e pode informar se outro evento aconteceu enquanto você estava processando o evento em que você está trabalhando. ou seja,

  • Carregar documento
  • ler o número da versão antiga / última identificação do evento
  • adicionar imagem com o ID do evento
  • atualizar o número da versão
  • sobregravar doc se o número da versão for o mesmo / nenhum evento mais tiver sido adicionado
  • SE a versão foi alterada desde o início, refaça a operação.

Obviamente, isso não funciona bem se você tiver muitas colisões, pois está sempre refazendo as etapas. Além disso, você ainda precisa de algum tipo de transação suportada pelo banco de dados para a etapa final.

No entanto, vejo que o DocumentDb suporta transações:

Does DocumentDB support ACID transactions?

Yes, DocumentDB supports cross-document transactions expressed as JavaScript stored procedures

Sugiro que você crie uma transação reutilizável simples que apenas verifique se o número da versão do documento é o esperado. Você pode usar isso com todos os seus eventos.

    
por 07.03.2017 / 11:25
fonte