지속성 함수의 함수 체이닝 - Hello 시퀀스 샘플

함수 체이닝은 특정 순서로 일련의 함수를 실행하는 패턴을 나타냅니다. 종종 한 함수의 출력을 다른 함수의 입력에 적용해야 합니다. 이 문서에서는 Durable Functions 빠른 시작(C#, JavaScript, TypeScript, Python, PowerShell 또는 Java)을 완료할 때 생성되는 체이닝 시퀀스에 대해 설명합니다. Durable Functions에 대한 자세한 내용은 Durable Functions 개요를 참조하세요.

필수 조건

참고 항목

Azure Functions용 Node.js 프로그래밍 모델 버전 4가 일반 공급됩니다. 새로운 v4 모델은 JavaScript 및 TypeScript 개발자에게 보다 유연하고 직관적인 환경을 제공하도록 설계되었습니다. 마이그레이션 가이드에서 v3과 v4의 차이점에 대해 자세히 알아봅니다.

다음 코드 조각에서 JavaScript(PM4)는 새로운 환경인 프로그래밍 모델 V4를 나타냅니다.

함수

이 문서에서는 샘플 앱의 다음 함수에 대해 설명합니다.

  • E1_HelloSequence: 시퀀스에서 E1_SayHello를 여러 번 호출하는 오케스트레이터 함수입니다. E1_SayHello 호출의 출력을 저장하고 결과를 기록합니다.
  • E1_SayHello: 문자열 앞에 "Hello"가 추가되는 작업 함수입니다.
  • HttpStart: 오케스트레이터의 인스턴스를 시작하는 HTTP 트리거 지속형 클라이언트 함수입니다.

E1_HelloSequence 오케스트레이터 함수

[FunctionName("E1_HelloSequence")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("E1_SayHello_DirectInput", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

모든 C# 오케스트레이션 함수에는 Microsoft.Azure.WebJobs.Extensions.DurableTask 어셈블리에 있는 DurableOrchestrationContext 유형 매개 변수가 있어야 합니다. 이 컨텍스트 개체를 사용하면 다른 작업 함수를 호출하고 해당 CallActivityAsync 메서드를 사용하여 입력 매개 변수를 전달할 수 있습니다.

코드에서는 여러 매개 변수 값을 사용하여 E1_SayHello을 순서대로 세 번 호출합니다. 각 호출의 반환 값은 함수의 끝에서 반환되는 outputs 목록에 추가됩니다.

E1_SayHello 작업 함수

[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에 바인딩하는 대신 작업 함수로 전달되는 형식에 직접 바인딩할 수 있습니다. 예시:

[FunctionName("E1_SayHello_DirectInput")]
public static string SayHelloDirectInput([ActivityTrigger] string name)
{
    return $"Hello {name}!";
}

HttpStart 클라이언트 함수

클라이언트 함수를 사용하여 오케스트레이터 함수의 인스턴스를 시작할 수 있습니다. HttpStart HTTP 트리거 함수를 사용하여 E1_HelloSequence의 인스턴스를 시작합니다.

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 입력 바인딩이 포함되어야 합니다. 클라이언트를 사용하여 오케스트레이션을 시작합니다. 또한 새 오케스트레이션의 상태를 확인하기 위해 URL이 포함된 HTTP 응답을 반환하는 데 도움이 될 수 있습니다.

샘플 실행

E1_HelloSequence 오케스트레이션을 실행하려면 다음 HTTP POST 요청을 HttpStart 함수로 전송합니다.

POST http://{host}/orchestrators/E1_HelloSequence

참고 항목

이전 HTTP 코드 조각에서는 모든 HTTP 트리거 함수 URL에서 기본 api/ 접두사를 제거하는 항목이 host.json 파일에 있다고 가정합니다. 샘플의 host.json 파일에서 이 구성에 대한 변경 내용을 찾을 수 있습니다.

예를 들어 "myfunctionapp"이라는 함수 앱에서 샘플을 실행하는 경우 "{host}"를 "myfunctionapp.azurewebsites.net"으로 바꿉니다.

결과는 다음과 같은 HTTP 202 응답입니다(간결하게 정리되었음).

HTTP/1.1 202 Accepted
Content-Length: 719
Content-Type: application/json; charset=utf-8
Location: http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

(...trimmed...)

이 시점에서 오케스트레이션은 큐에서 대기한 다음 즉시 실행되기 시작합니다. Location 헤더의 URL을 사용하여 실행 상태를 확인할 수 있습니다.

GET http://{host}/runtime/webhooks/durabletask/instances/96924899c16d43b08a536de376ac786b?taskHub=DurableFunctionsHub&connection=Storage&code={systemKey}

결과는 오케스트레이션의 상태입니다. 빠르게 실행되고 완료되므로 다음과 같은 응답과 함께 완료됨 상태로 표시됩니다(간결하게 정리되었음).

HTTP/1.1 200 OK
Content-Length: 179
Content-Type: application/json; charset=utf-8

{"runtimeStatus":"Completed","input":null,"output":["Hello Tokyo!","Hello Seattle!","Hello London!"],"createdTime":"2017-06-29T05:24:57Z","lastUpdatedTime":"2017-06-29T05:24:59Z"}

여기서 볼 수 있듯이 인스턴스의 runtimeStatus완료됨이고 output에는 JSON 직렬화된 오케스트레이터 함수 실행 결과가 포함됩니다.

참고 항목

queueTrigger, eventHubTrigger 또는 timerTrigger와 같은 다른 트리거 형식에 대해 비슷한 시작 논리를 구현할 수 있습니다.

함수 실행 로그를 검토합니다. E1_HelloSequence 함수는 오케스트레이션 안정성 토픽에서 설명한 재생 동작으로 인해 여러 번 시작되고 완료되었습니다. 반면에 이러한 함수 실행이 재생되지 않으므로 E1_SayHello는 3회만 실행되었습니다.

다음 단계

이 샘플은 간단한 함수 체인 오케스트레이션을 보여 주었습니다. 다음 예제는 팬아웃/팬인 패턴의 구현 방법을 보여줍니다.