Nservicebus 传奇超时
Nservicebus saga timeout
我有一个 saga,它每 30 秒检查一次 API 调用的状态,如果从调用返回的状态成功,则 saga 结束,否则
传奇等待 30 秒,然后再次尝试。如果 API 调用在 60 分钟内未返回成功响应,则 saga 超时并结束。
我在触发 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;
}
}
谁能看出我错在哪里?
谢谢
你的 Saga 应该闲置了。你用一个 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;
}
}
另一个评论可能是 Saga 本身不应该调用外部服务。甚至最好不要访问某些数据库。将此委托给另一个服务。每 30 秒向另一个处理程序发送一条消息。此处理程序应调用 WebService/WebAPI。当它可以确认一切正确时,回复原来的 Saga。当它不正确时,就顺其自然吧。 Saga 将每 30 秒发送一次消息以重试。
60 分钟后,Saga 应该停止发送消息和 MarkAsComplete。
我有一个 saga,它每 30 秒检查一次 API 调用的状态,如果从调用返回的状态成功,则 saga 结束,否则 传奇等待 30 秒,然后再次尝试。如果 API 调用在 60 分钟内未返回成功响应,则 saga 超时并结束。
我在触发 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;
}
}
谁能看出我错在哪里?
谢谢
你的 Saga 应该闲置了。你用一个 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;
}
}
另一个评论可能是 Saga 本身不应该调用外部服务。甚至最好不要访问某些数据库。将此委托给另一个服务。每 30 秒向另一个处理程序发送一条消息。此处理程序应调用 WebService/WebAPI。当它可以确认一切正确时,回复原来的 Saga。当它不正确时,就顺其自然吧。 Saga 将每 30 秒发送一次消息以重试。
60 分钟后,Saga 应该停止发送消息和 MarkAsComplete。