Одноэлементные экземпляры в устойчивых функциях (Функции Azure)

Для фоновых заданий часто требуется, чтобы в любой момент времени выполнялся только один экземпляр определенного оркестратора. Такое поведение можно обеспечить в расширении Устойчивые функции, назначив оркестратору определенный идентификатор экземпляра при его создании.

Пример одноэлементного экземпляра

В следующем примере показана функция для HTTP-триггеров, которая создает отдельный экземпляр для фоновой оркестрации заданий. Код обеспечивает наличие только одного экземпляра с указанным идентификатором.

[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."),
        };
    }
}

Примечание

Предыдущий пример C# предназначен для Устойчивых функций версии 2.x. Для Устойчивых функций версии 1.x нужно указать атрибут OrchestrationClient вместо DurableClient и тип параметра DurableOrchestrationClient вместо IDurableOrchestrationClient. Дополнительные сведения о различиях между версиями см. в статье Версии устойчивых функций.

По умолчанию идентификаторы экземпляров — это случайным образом сгенерированные GUID. Но в предыдущем примере идентификатор экземпляра передается в данных о маршруте, полученных из URL-адреса. Затем код извлекает метаданные экземпляра оркестрации, чтобы проверить, запущен ли экземпляр с указанным идентификатором. Если такого экземпляра нет, создается новый экземпляр с указанным идентификатором.

Примечание

В этом примере содержится потенциальное состояние гонки. Если два экземпляра HttpStartSingle выполняются параллельно, оба вызова функции сообщат об успешном выполнении, но фактически запустится только один экземпляр оркестрации. В зависимости от применяемых требований это может привести к нежелательным побочным эффектам.

Детали реализации функции оркестратора не имеют особого значения. Это может быть обычная функция оркестратора, которая начинает и завершает работу, или же выполняющаяся бесконечно (т. е. вечная оркестрация). Важно то, что в любой момент времени выполняется только один экземпляр.

Дальнейшие действия