我有一个传奇,每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;
    }

}


谁能看到我要去哪里错了?

谢谢

最佳答案

你的传奇应该闲着。您可以使用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。

10-07 21:03