Orquestradores singleton no Durable Functions (Funções do Azure)
Para tarefas em segundo plano, muitas vezes tem de garantir que apenas uma instância de um orquestrador específico é executada de cada vez. Pode garantir este tipo de comportamento singleton no Durable Functions ao atribuir um ID de instância específico a um orquestrador ao criá-lo.
Exemplo singleton
O exemplo seguinte mostra uma função de acionador HTTP que cria uma orquestração de tarefas em segundo plano singleton. O código garante que existe apenas uma instância para um ID de instância especificado.
[FunctionName("HttpStartSingle")]
public static async Task<HttpResponseMessage> RunSingle(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}/{instanceId}")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
string functionName,
string instanceId,
ILogger log)
{
// Check if an instance with the specified ID already exists or an existing one stopped running(completed/failed/terminated).
var existingInstance = await starter.GetStatusAsync(instanceId);
if (existingInstance == null
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Completed
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Failed
|| existingInstance.RuntimeStatus == OrchestrationRuntimeStatus.Terminated)
{
// An instance with the specified ID doesn't exist or an existing one stopped running, create one.
dynamic eventData = await req.Content.ReadAsAsync<object>();
await starter.StartNewAsync(functionName, instanceId, eventData);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
else
{
// An instance with the specified ID exists or an existing one still running, don't create one.
return new HttpResponseMessage(HttpStatusCode.Conflict)
{
Content = new StringContent($"An instance with ID '{instanceId}' already exists."),
};
}
}
Nota
O código C# anterior destina-se a Durable Functions 2.x. Para Durable Functions 1.x, tem de utilizar OrchestrationClient
o atributo em vez do DurableClient
atributo e tem de utilizar o DurableOrchestrationClient
tipo de parâmetro em vez de IDurableOrchestrationClient
. Para obter mais informações sobre as diferenças entre versões, veja o artigo Durable Functions versões.
Por predefinição, os IDs de instância são GUIDs gerados aleatoriamente. No exemplo anterior, no entanto, o ID da instância é transmitido nos dados de rota do URL. Em seguida, o código obtém os metadados da instância de orquestração para verificar se uma instância com o ID especificado já está em execução. Se nenhuma instância estiver em execução, é criada uma nova instância com esse ID.
Nota
Existe uma potencial condição race neste exemplo. Se duas instâncias de HttpStartSingle forem executadas em simultâneo, ambas as chamadas de função comunicarão êxito, mas apenas uma instância de orquestração será realmente iniciada. Dependendo dos seus requisitos, isto pode ter efeitos colaterais indesejáveis.
Os detalhes de implementação da função orchestrator não são realmente importantes. Pode ser uma função de orquestrador regular que começa e conclui, ou pode ser uma função que funciona para sempre (ou seja, uma Orquestração Eterna). O importante é que há apenas uma instância em execução de cada vez.