我有一个saga,如果从调用返回的状态成功,saga结束,则每隔30秒检查一次API调用的状态,如果没有 传奇等待30秒并再次尝试。如果API调用在60分钟内没有返回成功的响应,那么传奇会超时并结束。
我在解除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;
}
}
谁能看到我哪里出错了?
感谢
答案 0 :(得分:5)
你的传奇应该闲着。你通过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分钟后,Saga应该停止发送消息和MarkAsComplete。