2015-11-19 49 views
1

我有一個傳奇,每30秒檢查一次API的狀態,如果從通話返回的狀態成功,傳奇結束,如果不是這樣,傳奇等待30秒,然後再次嘗試。如果API調用在60分鐘內沒有返回成功響應,則該事件超時並結束。Nservicebus傳奇超時

我有問題讓我的60分鐘超時啓動。我的代碼是

public class MonitorSubmissionFeedSagaData: IContainSagaData 
{ 
    public Guid Id { get; set; } 

    public string Originator { get; set; } 

    public string OriginalMessageId { get; set; } 

    public bool TimeoutSet { get; set; } 

    [Unique] 
    public string JobId { get; set; } 
} 

public class MonitorSubmissionFeedSaga : Saga<MonitorSubmissionFeedSagaData>, 
    IAmStartedByMessages<MonitorFeedSubmissonCommand>, 
    IHandleMessages<StartCheckSubmissionCommand>, 
    IHandleTimeouts<MonitorSubmissionFeedSagaTimeout> 
{ 
    public const int SagaTimeoutInMinutes = 60; 

    public IEmpathyBrokerClientApi PostFileService { get; set; } 

    protected override void ConfigureHowToFindSaga(SagaPropertyMapper<MonitorSubmissionFeedSagaData> mapper) 
    { 
     mapper.ConfigureMapping<MonitorFeedSubmissonCommand>(x => x.JobId).ToSaga(saga => saga.JobId); 

    } 

    public void Handle(MonitorFeedSubmissonCommand message) 
    { 
     Data.JobId = message.JobId; 

     CheckTimeout(); 

     Bus.Send(new StartCheckSubmissionCommand 
     { 
      JobId = Data.JobId 
     }); 
    } 

    public void Handle(StartCheckSubmissionCommand message) 
    { 
     Log.Info("Saga with JobId {0} received", Data.JobId); 

     bool isCompleted = GetJobStatus(message.JobId); 

     while (isCompleted) 
     { 
      Thread.Sleep(30000); 
      isCompleted = GetJobStatus(message.JobId); 
     } 

     MarkAsComplete(); 
    } 

    public void CheckTimeout() 
    { 
     RequestTimeout<MonitorSubmissionFeedSagaTimeout>(TimeSpan.FromMinutes(SagaTimeoutInMinutes)); 
    } 

    public void Timeout(MonitorSubmissionFeedSagaTimeout state) 
    { 
     MarkAsComplete(); 
    } 

    bool GetJobStatus(string jobId) 
    { 
     return false; 
     var status = PostFileService.GetJobIdStatus(jobId); 
     if (status.state == "FAILURE" || status.state == "DISCARDED") 
     { 
      return false; 
     } 
     return true; 
    } 

} 

任何人都可以看到我要去哪裏錯了嗎?

謝謝

回答

4

你的佐賀人應該閒置。你用一個while循環保持它活着。超時消息在某個時刻到達,然後您應該檢查應該發生什麼。要麼結賬或MarkAsComplete。

我在記事本中寫了這個,所以可能無法編譯。但是,這是一個想法。

public class MonitorSubmissionFeedSagaData: IContainSagaData 
{ 
public Guid Id { get; set; } 
public string Originator { get; set; } 
public string OriginalMessageId { get; set; } 

[Unique] 
public string JobId { get; set; } 
public DateTime SagaStartTimeUtc { get; set; } 
} 

public class MonitorSubmissionFeedSaga : Saga<MonitorSubmissionFeedSagaData>, 
    IAmStartedByMessages<MonitorFeedSubmissonCommand>, 
    IHandleTimeouts<VerifyApiTimeOut> 
{ 
public IEmpathyBrokerClientApi PostFileService { get; set; } 

public void Handle(MonitorFeedSubmissonCommand message) 
{ 
    Data.JobId = message.JobId; 
    Data.SagaStartTimeUtc = DateTime.NowUtc; 

    CreateTimeoutRequest(); 
} 

public void CreateTimeoutRequest() 
{ 
    RequestTimeout<VerifyApiTimeOut>(TimeSpan.FromSeconds(30)); 
} 

public void Timeout(VerifyApiTimeOut state) 
{ 
    if (!GetJobStatus(Data.JobId) && DateTime.NowUtc < Data.SagaStartTimeUtc.AddMinutes(60)) 
    { 
     CreateTimeoutRequest(); 
    } 

    MarkAsComplete(); 
} 

bool GetJobStatus(string jobId) 
{ 
    return false; 
    var status = PostFileService.GetJobIdStatus(jobId); 
    if (status.state == "FAILURE" || status.state == "DISCARDED") 
    { 
     return false; 
    } 
    return true; 
} 

} 

另一個意見可能是,佐賀本身不應該呼喚對外服務。最好不要對某些數據庫。將其委派給其他服務。每隔30秒,發送一條消息給另​​一個處理程序。這個處理程序應該調用WebService/WebAPI。當它可以確認一切正確時,回覆原來的佐賀。當它不正確時,就讓它成爲。傳奇將每30秒發出一次消息重試。

60分鐘後,佐賀應停止發送消息和MarkAsComplete。