Цепочки функций в устойчивых функциях — пример последовательности Hello
Статья
Цепочкой функций называют схему выполнения последовательности функций в определенном порядке. Часто требуется передать выходные данные одной функции во входные данные другой. В этой статье описывается последовательность цепочки, созданная при выполнении краткого руководства по Устойчивые функции (C#, JavaScript, TypeScript, Python, PowerShell или Java). Дополнительные сведения об Устойчивых функций см. в статье, посвященной обзору Устойчивых функций.
Общедоступна версия 4 модели программирования Node.js для Функции Azure. Новая модель версии 4 предназначена для более гибкого и интуитивно понятного интерфейса для разработчиков JavaScript и TypeScript. Дополнительные сведения о различиях между версиями 3 и 4 см. в руководстве по миграции.
В следующих фрагментах кода JavaScript (PM4) обозначает модель программирования версии 4, новый интерфейс.
Функции
В этой статье описаны следующие функции в примере приложения:
E1_HelloSequence. Функция оркестратора, вызывающая E1_SayHello несколько раз подряд. При этом сохраняются выходные данные каждого вызова E1_SayHello и записываются результаты.
E1_SayHello. Функция действия, которая добавляет Hello в начало строки.
HttpStart: Функция долговременного клиента, активируемая по протоколу HTTP, которая запускает экземпляр оркестратора.
Для всех функций оркестратора на C# должен использоваться параметр типа DurableOrchestrationContext, который присутствует в сборке Microsoft.Azure.WebJobs.Extensions.DurableTask. Этот объект контекста позволяет вызывать другие функции действия и передавать им входные параметры с помощью метода CallActivityAsync.
Этот код трижды последовательно вызывает E1_SayHello с разными значениями параметров. Значение, возвращаемое при каждом вызове, добавляется в список outputs, который возвращается в качестве результата функции.
function.json
Если вы используете для разработки Visual Studio Code или портал Azure, файл function.json с указанным здесь содержимым позволит создать функцию оркестратора. Для большинства функций оркестратора файл function.json будет выглядеть почти так же.
Самое важное здесь — это тип привязки orchestrationTrigger. Во всех функциях оркестратора должен использоваться такой тип триггера.
Предупреждение
Чтобы не нарушать требование "без ввода и вывода", применяемое к функциям оркестратора, не используйте никакие привязки входных или выходных данных совместно с триггером привязки orchestrationTrigger. Если вам нужны входные или выходные привязки, используйте их в контексте функций activityTrigger, которые вызываются оркестратором. Дополнительные сведения см. в статье об ограничениях кода функции оркестратора.
Все функции оркестратора на JavaScript должны содержать модуль durable-functions. Это библиотека, позволяющая записывать Устойчивые функции на языке JavaScript. Есть три существенных различия между функцией оркестратора и другими функциями JavaScript:
Эта функция упаковывается в вызов к методу orchestrator модуля durable-functions (в нашем примере это df).
Функции должны быть синхронными. Так как метод orchestrator обрабатывает окончательный вызов аргумента context.done, функция должна возвращать значение.
Объект context содержит объект контекста надежной оркестровки df, что позволяет вызывать другие функции действий и передавать им входные параметры с помощью метода callActivity. Этот код вызывает E1_SayHello три раза подряд с разными значениями параметров, указывая с помощью yield, что процесс выполнения должен ожидать возврата из асинхронных функций действий. Значение, возвращаемое при каждом вызове, добавляется в массив outputs, который возвращается при завершении функции.
Все функции оркестратора на JavaScript должны содержать модуль durable-functions. Этот модуль позволяет писать Устойчивые функции в JavaScript. Чтобы использовать модель программирования узлов версии 4, необходимо установить предварительную v3.x версию durable-functions.
Существует два существенных различия между функцией оркестратора и другими функциями JavaScript:
Функции должны быть синхронными. Функция должна просто вернуться.
Объект context содержит объект контекста надежной оркестровки df, что позволяет вызывать другие функции действий и передавать им входные параметры с помощью метода callActivity. Этот код вызывает sayHello три раза подряд с разными значениями параметров, указывая с помощью yield, что процесс выполнения должен ожидать возврата из асинхронных функций действий. Значение, возвращаемое при каждом вызове, добавляется в массив outputs, который возвращается при завершении функции.
Примечание.
Устойчивые функции Python доступны только для среды выполнения Функции Azure 3.0.
function.json
Если вы используете для разработки Visual Studio Code или портал Azure, файл function.json с указанным здесь содержимым позволит создать функцию оркестратора. Для большинства функций оркестратора файл function.json будет выглядеть почти так же.
Самое важное здесь — это тип привязки orchestrationTrigger. Во всех функциях оркестратора должен использоваться такой тип триггера.
Предупреждение
Чтобы не нарушать требование "без ввода и вывода", применяемое к функциям оркестратора, не используйте никакие привязки входных или выходных данных совместно с триггером привязки orchestrationTrigger. Если вам нужны входные или выходные привязки, используйте их в контексте функций activityTrigger, которые вызываются оркестратором. Дополнительные сведения см. в статье об ограничениях кода функции оркестратора.
Все функции оркестрации в Python должны включать durable-functions пакет. Это библиотека, позволяющая записывать Устойчивые функции на языке Python. Есть два существенных различия между функцией оркестратора и другими функциями Python:
Файл должен зарегистрировать функцию оркестратора в качестве оркестратора, указывая main = df.Orchestrator.create(<orchestrator function name>) в конце файла. Это помогает отличать ее от других, вспомогательных функций, объявленных в файле.
Этот объект context позволяет вызывать другие функции действия и передавать им входные параметры с помощью метода call_activity. Этот код вызывает E1_SayHello три раза подряд с разными значениями параметров, указывая с помощью yield, что процесс выполнения должен ожидать возврата из асинхронных функций действий. Значение, возвращаемое при каждом вызове, возвращается при завершении функции.
[FunctionName("E1_SayHello")]
public static string SayHello([ActivityTrigger] IDurableActivityContext context)
{
string name = context.GetInput<string>();
return $"Hello {name}!";
}
Действия используют атрибут ActivityTrigger. Используйте предоставленный IDurableActivityContext для выполнения действий, связанных с операциями, например для доступа к входному значению с помощью GetInput<T>.
Функция E1_SayHello реализует достаточно простую операцию форматирования строки.
Вместо привязки к IDurableActivityContext можно выполнить прямую привязку к типу, передаваемому в функцию действия. Например:
Файл Function.json для функции действия E1_SayHello будет таким же, как и для E1_HelloSequence, с одним исключением: в нем используется тип привязки activityTrigger вместо orchestrationTrigger.
Для любой функции действия, которую вызывает функция оркестрации, должна использоваться привязка activityTrigger.
Функция E1_SayHello реализует достаточно простую операцию форматирования строки.
E1_SayHello/index.js
module.exports = function (context) {
context.done(null, `Hello ${context.bindings.name}!`);
};
В отличие от функции оркестрации, функция действия не требует дополнительной настройки. Входные данные, которые ей передает функция оркестратора, размещаются в объекте context.bindings под именем привязки activityTrigger (в нашем примере это context.bindings.name). Имя привязки можно задать в качестве параметра экспортируемой функции и обращаться к нему напрямую, как показано в этом примере кода.
Функция sayHello реализует достаточно простую операцию форматирования строки.
В отличие от функции оркестрации, функция действия не требует дополнительной настройки. Входные данные, переданные функцией оркестратора, являются первым аргументом функции. Второй аргумент — это контекст вызова, который не используется в этом примере.
E1_SayHello/function.json
Файл Function.json для функции действия E1_SayHello будет таким же, как и для E1_HelloSequence, с одним исключением: в нем используется тип привязки activityTrigger вместо orchestrationTrigger.
В отличие от функции оркестратора, для функции действия не требуется специальной настройки. Входные данные, передаваемые ей функцией оркестратора, напрямую доступны в качестве параметра функции.
Функция клиента HttpStart
Экземпляр функции оркестратора можно запустить с помощью функции клиента. HttpStartДля запуска экземпляров E1_HelloSequence будет использоваться функция, активируемая HTTP.
public static class HttpStart
{
[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
[DurableClient] IDurableClient starter,
string functionName,
ILogger log)
{
// Function input comes from the request content.
object eventData = await req.Content.ReadAsAsync<object>();
string instanceId = await starter.StartNewAsync(functionName, eventData);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
Для взаимодействия с оркестраторами функция должна включать входную привязку DurableClient. Для запуска оркестрации используется клиент. Он также может помочь вернуть ответ HTTP, содержащий URL-адреса для проверки состояния новой оркестрации.
Для получения объекта DurableOrchestrationClient используйте командлет df.getClient. Для запуска оркестрации используется клиент. Он также может помочь вернуть ответ HTTP, содержащий URL-адреса для проверки состояния новой оркестрации.
Для управления оркестраторами и взаимодействия с ней требуется входная durableClient привязка. Эта привязка должна быть указана в аргументе extraInputs при регистрации функции. Входные durableClient данные можно получить путем вызова df.input.durableClient().
Для получения объекта DurableClient используйте командлет df.getClient. Для запуска оркестрации используется клиент. Он также может помочь вернуть ответ HTTP, содержащий URL-адреса для проверки состояния новой оркестрации.
Для взаимодействия с оркестраторами функция должна включать входную привязку durableClient.
HttpStart/__init__.py
import logging
import azure.functions as func
import azure.durable_functions as df
async def main(req: func.HttpRequest, starter: str) -> func.HttpResponse:
client = df.DurableOrchestrationClient(starter)
instance_id = await client.start_new(req.route_params["functionName"], None, None)
logging.info(f"Started orchestration with ID = '{instance_id}'.")
return client.create_check_status_response(req, instance_id)
Используйте конструктор DurableOrchestrationClient для получения клиента Устойчивых функций. Для запуска оркестрации используется клиент. Он также может помочь вернуть ответ HTTP, содержащий URL-адреса для проверки состояния новой оркестрации.
Запуск примера
Чтобы запустить оркестрацию E1_HelloSequence, отправьте указанный ниже запрос HTTP POST в функцию HttpStart.
POST http://{host}/orchestrators/E1_HelloSequence
Примечание.
В предыдущем фрагменте HTTP предполагается, что в файле host.json существует запись, которая позволяет удалить префикс api/ по умолчанию из всех URL-адресов функций для триггеров HTTP. Разметку для этой конфигурации можно найти в файле host.json в примерах.
Скажем, если пример выполняется в приложении-функции с именем myfunctionapp, замените {host} значением myfunctionapp.azurewebsites.net.
Вы получите примерно такой ответ HTTP с кодом 202 (фрагмент ответа):
Функция оркестратора помещается в очередь и немедленно передается на выполнение. URL-адрес из заголовка Location позволяет проверить состояние выполнения функции.
GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}
В ответе на такой запрос возвращаются сведения о состоянии оркестрации. Функция выполняется и завершается достаточно быстро, поэтому, вероятнее всего, отобразится состояние Завершено в ответе примерно такого вида (фрагмент ответа):
Как видите, параметр runtimeStatus для экземпляра имеет значение Завершено, а output содержит результат выполнения функции оркестратора, сериализованный в формате JSON.
Примечание.
Вы можете использовать аналогичную логику запуска и для других типов триггеров, например queueTrigger, eventHubTrigger или timerTrigger.
Просмотрите журналы выполнения функции. Функция E1_HelloSequence была запущена и завершена несколько раз в соответствии с логикой повторов, описанной в разделе о надежности оркестрации. С другой стороны, функция E1_SayHello выполнялась только три раза, поскольку для таких процессов логика повторов не применяется.
Следующие шаги
В этом примере показана простая оркестрация с цепочкой функций. В приведенном ниже примере кода показана реализация шаблона развертывания и объединения.