Windows Azure 용 작업자 역할을 쓰고 있습니다. 작업자는 대기열에서 메시지를 수신하고 모든 메시지에 대해 스레드를 회전시킵니다. 스레드가 외부 API를 호출하고 대기중인 스레드가 많이 발생합니다. 즉, "인스턴스 생성"을 호출 할 수 있으며 API는 202 Accepted
을 반환하고 "완료"응답을 위해 API를 폴링해야합니다. 때때로 대기 시간은 5 분이 될 수 있습니다. 전체 프로세스는 10 분에서 30 분이 소요될 수 있으며 약 10 회의 API 호출이 가능합니다.충돌 후 동일한 위치에서 스레드 시작
Azure Worker의 수명이 30 분입니다. 역할이 상당하기 때문에 해당 시간에 Restart/Redeploy/Crash가 발생할 수 있습니다. 그리고 제 프로세스는 멱등수가 아닙니다. 동일한 리소스를 문제없이 두 번 만들 수는 없습니다.
내가하고 싶은 것은 API에 대한 모든 중요한 호출에 스레드의 상태를 어딘가에 저장하는 것입니다. 따라서 스레드가 어딘가에 충돌하면 다른 작업자 역할이 대기열에서 메시지를 가져 와서 이전 프로세스가 중단 된 동일한 프로세스 지점에서 벗어날 수 있습니다.
아이디어 중 하나는 스레드 상태를보고 어딘가에 유지하는 것이 었습니다. 이 의사처럼 뭔가 :
pubilc class WorkerRole{
public override Run(){
while(true)
{
var message = Queue.GetMessage();
var messageProcessor = new MessageProcessor(message);
var thread = new Thread();
thread.Run(messageProcessor.Process());
Thread.Sleep(1 minute);
}
}
}
public class MessageProcessor
{
private QueueMessage message;
public MessageProcessor(QueueMessage message){
this.message = message
}
public void Process()
{
if(!ThreadReporter.IsComplete(message, "Step1")
{
ExtenalApi.StartStep1();
}
ThreadReporter.ReportCompletion(message, "Step1");
if(!ThreadReporter.IsComplete(message, "Step2"))
{
ExternalApi.StartStep2();
}
ThreadReporter.ReportCompletion(message, "Step2");
}
}
ThreadReporter
어딘가에 1 단계가 완료 또는 1 단계에 대한 플래그가 이미 특정 메시지 (작업 요청) 설정되어 있는지 확인 할 DB에 플래그를 저장한다.
이 접근 방식은 많은 문제가있을 수 있으며 코드는 끔찍할 것이라고 생각할 수 있습니다. 그러나 나는 그것을하는 더 좋은 방법에 대해 생각하기 위해 투쟁합니다.
저는 Jon Skeet이 응용 프로그램의 MemoryDump를 저장하고 있고 같은 위치에서 다시 시작한 것을 본 적이 있습니다. 스레드 상태를 직렬화하여 DB에 저장할 수 있습니까?
또한 Workflow Foundation에서도이를 수행 할 수 있다고 들었습니다. 나는 WF와 함께 일한 적이 없으며 그것에 대해 전혀 모른다. WF에 대한 힌트가 있습니까?
그래서 문제는 충돌 후 마지막 지점부터 시작할 수있는 워크 플로 (본질적으로 워크 플로)를 구현하는 가장 좋은 방법은 무엇입니까?
나는 이미 이런 것들을 알고있었습니다! 올바른 방향을 가리켜 주셔서 감사합니다. 응용 프로그램은 아직 프로토 타입 단계에 있으므로 _re_ architecting에서 필요가 없으며 ** architecting ** - 만 필요합니다. 그리고 어쨌든 WF로 옮길 생각이었습니다! – trailmax
예. 그것은 나를위한 최근의 "배움"이었습니다. 그들은 아주 차갑다. –