워크플로 관리자 1.0으로 새 버전의 워크플로 또는 사용자 지정 작업 추가

 

워크플로를 개발하는 동안에는 버그를 수정해야 하거나 비즈니스 요구 사항이 변화하는 까닭에 작업 정의를 변경해야 하는 경우가 많습니다.이 경우 이전에 게시했던 작업 정의나 워크플로 정의를 새롭게 수정한 버전을 만들 수 있습니다.이 항목에서는 Workflow Manager 1.0에서 제공하는 버전 관리 기능을 간략하게 살펴보고 이러한 기능을 시나리오에 적용하는 방법을 설명합니다.

워크플로 버전 관리 개요

Workflow Manager 1.0에서는 작업 및 워크플로 정의를 업데이트할 수 있습니다.작업 또는 워크플로 정의를 업데이트하는 일에 불과해 보일 수도 있지만 이 업데이트만으로 버전 관리 매커니즘을 내부적으로 트리거할 수 있습니다.예를 들어 LoanProcessing 작업을 사용한 EligibilityCheck 워크플로가 있는데 EligibilityCheck 작업의 버그를 수정하려는 경우, 이 작업을 새 정의로 업데이트기하기만 합니다.하지만 이 작업을 참조하는 기존 워크플로는 어떻게 됩니까?기존 워크플로는 이전 정의나 새 정의 중 무엇을 사용해야 합니까?기존 인스턴스는 어떤 구현을 사용하며,새 인스턴스는 어떤 구현을 사용합니까?

이와 비슷하게 500,000달러가 넘는 대출에 대한 추가 승인자 단계가 포함되도록 LoanProcessing 워크플로를 업데이트할 수도 있습니다.이 경우에도 다음과 같은 질문을 던지게 됩니다. 기존 인스턴스는 어떻게 됩니까?기존 인스턴스는 이전 정의나 새 정의 중 무엇을 사용하게 됩니까?새 인스턴스는 어떤 버전을 사용합니까?

이 항목의 섹션에서는 이러한 시나리오를 구현하는 방법을 설명하고, Workflow Manager 1.0의 버전 관리 기능에 대한 개요를 제공합니다.

워크플로 수정 버전

이제부터 워크플로 수정 버전의 시나리오에 대해 살펴보겠습니다.LoanProcessing이라는 워크플로가 있습니다.LoanProcessing에는 EligibilityCheck 작업이 포함되어 있습니다.EligibilityCheck 작업과 LoanProcessing 워크플로는 Workflow Manager 1.0에 이미 게시되었습니다.이제 LoanProcessing 워크플로의 수정 버전을 만들어 워크플로 논리의 버그를 수정해야 합니다.필요한 내용을 변경하면 PublishWorkflow 클래스에서 WorkflowResourceManager 메서드를 호출할 수 있습니다(또는 REST API를 직접 호출할 경우 워크플로 리소스에서 HTTP PUT 사용).이 작업의 일환으로 Workflow Manager 1.0는 이 호출의 일부로 전달된 정의를 사용하여 이 워크플로의 새 버전을 내부적으로 만듭니다.버그 수정 특성에 따라 기존 인스턴스가 시작될 때 사용된 이전 정의를 사용하여 기존 인스턴스를 종료하거나 계속 실행하도록 선택할 수 있습니다.워크플로를 게시하려면 PublishWorkflow 메서드를 사용합니다.다음 예제에서는 구현으로 LoanProcessing를 사용하는 EligibilityCheck 워크플로를 게시합니다.

WorkflowDescription wfDesc = new WorkflowDescription();
wfDesc.Name = "LoanProcessing";
wfDesc.ActivityPath = "EligibilityCheck";
Uri wfUri = client.Workflows.Publish(wfDesc);

기존 인스턴스를 종료하려면 PublishWorkflow가 terminateActiveInstances로 설정된 true 메서드를 호출합니다.이 인스턴스를 false로 설정하거나 PublishWorkflow 매개 변수가 포함되지 않은 terminateActiveInstances 메서드의 오버로드를 호출해 false 값이 내부적으로 지정될 경우, 기존 인스턴스는 인스턴스화된 정의를 사용해 계속 실행됩니다.이 경우는 버그 수정 특성이 점진적인 시나리오에 적합합니다.예를 들어 LoanProcessingWorkflow가 변경되었지만 이 프로세스는 새로운 대출을 신청하는 경우에만 적용되도록 해야 하며, 기존 대출 고객과 통신했을 때 사용한 프로세스와 같은 이전 버전의 프로세스를 기존 대출 신청에 사용해도 문제가 없는 경우 terminateActiveInstances를 false로 설정할 수 있습니다.위의 예제에서는 PublishWorkflow 매개 변수를 사용하지 않은 terminateActiveInstances의 오버로드가 호출되었으므로 기존 인스턴스가 종료되지 않습니다.

버그 수정이 중요하고 기존 인스턴스를 종료하려는 경우(예: 대출 프로세싱 워크플로에서 실수로 모든 신청을 승인한 경우), terminateActiveInstances를 true로 설정해 정의를 업데이트할 수 있습니다.활성 인스턴스를 종료하는 프로세스는 비동기적이어서 즉각적으로 진행된다는 보장이 없으므로, 활성 인스턴스가 최종 종료될 때까지 계속 실행되는 인스턴스가 하나 이상 있을 수 있습니다.워크플로 수정 버전이 여러 개 있더라도 새 인스턴스를 만드는 데에는 최신 버전만 사용됩니다.마찬가지로 이 워크플로에 대한 GetWorkflow 호출이 이루어지면 워크플로의 최신 정의만 볼 수 있습니다.

작업 수정 버전

비즈니스 상황이 바뀜에 따라 EligibilityCheck 작업을 수정해야 하는 경우를 위에서 언급한 대출 승인 프로세스 예제를 계속 사용하여 가정해 보겠습니다.이 작업에 필요한 사항을 변경했으므로, 이제 EligibilityCheck에 대한 새 정의를 게시하고자 합니다.새 정의를 게시하려면 클라이언트에서 PublishActivity 메서드를 호출합니다(또는 작업의 리소스 URI가 포함된 HTTP PUT 메서드 호출).이 메서드를 호출하면 이 작업을 직간접적으로 사용하는 모든 작업과 워크플로가 새 버전을 사용하도록 내부적으로 업데이트되며, 이 작업을 직간접적으로 사용하는 워크플로의 새 인스턴스가 새 정의를 사용해 시작됩니다.

워크플로를 업데이트할 때와 같은 방식으로 작업을 업데이트할 때 기존 활성 인스턴스를 종료하도록 선택할 수 있습니다.하지만 종료하도록 선택하면 시스템에 끼치는 영향이 훨씬 더 클 수 있습니다.이를 이해하려면 워크플로가 하나 이상의 작업을 참조할 수 있고 작업이 0개 이상의 작업을 참조할 수 있다는 점을 기억해야 합니다.따라서 특정 작업은 0개 이상의 작업에서 참조될 수 있고 해당 작업은 0개 이상의 워크플로에서 참조될 수 있습니다.이는 곧 특정 작업이 여러 워크플로 정의에서 직간접적으로 참조될 수 있다는 뜻입니다.

작업을 업데이트하는 경우 워크플로를 업데이트할 때와 같은 결정을 내릴 수 있습니다.작업에 종속되어 있는 모든 워크플로의 인스턴스가 모두 이 업데이트 작업의 일환으로 종료될지, 아니면 이전 작업 정의를 사용하여 계속 실행될지를 선택해야 합니다.이 동작은 terminateDependentInstances 매개 변수에서 결정됩니다.terminateDependentInstances 매개 변수를 사용하지 않는 오버로드를 호출하면 종속 인스턴스가 종료되지 않아 이전 버전의 작업을 사용하게 됩니다.다음 예제에서는 TestActivity가 게시되며 종속 인스턴스는 종료되지 않습니다.

Activity newActivity = new Sequence
{
     ...
};

XElement activityXaml = XElement.Parse(XamlServices.Save(newActivity));

ActivityDescription activityDesc = new ActivityDescription();
activityDesc.SetXaml(activityXaml);

activityDesc.Name = "TestActivity";
client.Activities.Publish(activityDesc);

기존 작업 정의가 업데이트되면 Workflow Manager 1.0에서 다음을 수행합니다.

  1. 제공된 정의를 사용해 이 작업의 새 버전을 만듭니다.

  2. 이 작업의 새 버전을 사용하기 위해 이 작업을 참조하는 모든 워크플로 정의를 업데이트합니다.

  3. terminateDependentInstances가 true로 설정된 호출이 이루어지면 이 작업을 참조하는 모든 워크플로의 인스턴스가 모두 종료됩니다.

참고

위에 나열된 첫 번째 단계가 작업 정의를 업데이트하는 호출의 일부로 동기적으로 수행되면 나머지 단계가 비동기적으로 수행됩니다.이는 곧 특정 작업을 업데이트했더라도 해당 변경 사항이 이 작업을 참조하는 모든 워크플로에 적용되려면 몇 분이 걸릴 수 있다는 뜻입니다.따라서 이 시간 동안 이전 정의를 사용하는 워크플로가 있을 수 있습니다.하지만 이 비동기 프로세스가 완료되고 나면 이 작업을 참조하는 모든 워크플로가 이 작업의 최신 정의를 사용합니다.

참고

작업 수정 버전이 여러 개 있더라도 어느 시점에서든 이 중 하나만 활성화됩니다.나머지 수정 버전은 이 작업을 참조하는 워크플로의 기존 인스턴스를 지원하도록 내부적으로 유지 관리됩니다.그러므로 이 작업에 대한 Get 호출이 이루어지면 최신 작업 정의만 볼 수 있습니다.

워크플로 삭제

특정 워크플로가 더 이상 필요하지 않으면 이를 삭제하려는 경우가 있을 수 있습니다.LoanProcessing 워크플로에서 특정 유형의 대출 처리가 중단된 경우를 가정해 보겠습니다.인스턴스가 실수로 트리거되는 일이 발생하지 않도록 이 워크플로를 삭제할 수 있습니다.워크플로를 삭제하려면 클라이언트 API를 사용해 DeleteWorkflow 메서드를 호출하거나, 워크플로 리소스의 URI가 사용된 REST 끝점에서 DELETE를 호출합니다.워크플로를 삭제할 때에는 기존 인스턴스와 관련된 선택 사항이 두 가지 있습니다.비즈니스 결정에 따라 기존 대출은 완료되도록 처리하되 새로운 인스턴스는 허용하지 않을 경우 Delete에서 다음의 WorkflowManager 메서드를 호출할 수 있습니다.

public void Delete(string workflowName)

이 오버로드는 기존 인스턴스를 종료하지 않습니다.기존 인스턴스는 완료될 때까지 계속 처리됩니다.하지만 새 인스턴스는 워크플로 자체가 존재하지 않으므로 만들어지지 않습니다.따라서 이 워크플로의 새 인스턴스를 활성화하기 위해 메시지를 보내도 이 워크플로의 인스턴스가 활성화되지 않습니다.그러나 비즈니스 결정에 따라 기존 대출 신청도 종료할 경우에는 Delete 매개 변수를 사용하는 terminateActiveInstances 오버로드를 사용하고 이 매개 변수를 true로 지정합니다.

public void Delete(string workflowName, bool terminateActiveInstances)

그러면 새 인스턴스를 시작할 수 없어 실행 중인 인스턴스가 종료됩니다.

작업 삭제

매우 드문 경우지만 작업도 삭제해야 할 경우가 있을 수 있습니다.작업을 업데이트하는 경우와 마찬가지로 여러 워크플로가 작업을 직간접적으로 참조하여 삭제하면 영향을 받을 수 있습니다.클라이언트 API에서 Delete 메서드를 사용하거나 작업 리소스의 URI가 사용된 REST 끝점에서 DELETE를 호출해 작업을 삭제할 수 있습니다.이때에도 이 작업을 참조하는 워크플로의 기존 인스턴스와 관련된 선택 사항이 두 가지 있습니다.작업을 직간접적으로 참조하는 기존 인스턴스를 계속 실행하도록 하려면 Delete 매개 변수를 사용하지 않는 ActivityManager에서 terminateDependentInstances 메서드 오버로드를 호출하거나, 이 매개 변수를 사용하는 오버로드를 호출하고 매개 변수를 false로 설정합니다.

public void Delete(string activityName)

이 오버로드는 이 작업을 참조하는 워크플로의 기존 인스턴스를 종료하지 않습니다.하지만 이 작업이 새 인스턴스에 더 이상 존재하지 않으므로 이 작업을 참조하는 워크플로의 새 인스턴스는 만들어지지 않습니다.따라서 작업 중 하나가 누락되어 워크플로의 XAML을 완전하게 계산할 수 없음을 알려주는 로그에 런타임 예외가 발생합니다.

작업 삭제 동작과 워크플로 삭제 동작 사이에는 차이가 있습니다.워크플로 정의가 삭제되면 해당 워크플로의 인스턴스를 활성화하는 메시지가 무시됩니다.단, 작업이 삭제된 경우 이 작업을 참조하는 워크플로 정의가 모두 삭제되지는 않습니다.이러한 워크플로 정의는 계속 존재하므로 여기에 속한 메시지를 처리하려고 합니다.그러나 실행할 이 작업을 찾을 수 없게 되어 예외를 발생시키고 인스턴스를 종료합니다.이는 곧 특정 작업을 삭제했더라도 워크플로 정의는 계속 사용할 수 있다는 뜻입니다.삭제된 이 작업을 사용하지 않도록 워크플로 정의 논리를 수정하면 새 인스턴스가 제대로 실행되기 시작합니다.작업을 삭제할 때 기존 인스턴스를 종료하려면 Delete를 호출하고 terminateDependentInstances를 true로 설정합니다.그러면 이 작업을 참조하는 워크플로의 기존 인스턴스도 종료됩니다.

public void Delete(string activityName, bool terminateDependentInstances)