NServiceBus - 使用相同的密钥排队传单

时间:2016-01-04 14:11:22

标签: nservicebus nservicebus-sagas

方案: 我已经建立了一个有10个步骤的传奇。它正在更新各种系统,整个传奇可能需要几分钟才能完成。

该传奇是从另一个用户输入信息的系统的数据开始的。

我无法看到用户何时在系统中输入数据,但我每隔x分钟就会从系统中读取数据。

我的问题是,无论何时我开始使用客户数据的传奇,我都需要确保同一客户的先前传奇已经完成。 如果用户在输入数据上花了10分钟,系统可能会在同一个客户上启动5个流,并且流量可能会超过先前的流量,并且会使数据混乱。

有没有人知道如何解决这个问题?

提前致谢。

奥莱

2 个答案:

答案 0 :(得分:0)

如果不更改saga以及可能是客户端系统发送的消息,则无法解决此问题。

您的问题是,saga可能配置为在收到某种消息类型时启动,该消息类型是每次用户对客户进行更改时由客户端应用程序生成的。

让我们来电话:

public class ClientTypedSomethingAboutCustomer 
{
    int CustomerId {get;set;}
    ...
}

你的传奇将会是这样的:

public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
{
    public override void ConfigureHowToFindSaga()
    {
        ConfigureMapping<ClientTypedSomethingAboutCustomer>
            (message => message.CustomerId).ToSaga(saga => saga.CustomerId);
        ...
    }
    ...
}

这会导致为每个收到的客户端消息初始化saga并在IContainSagaData实现中设置Customer ID值。

要解决初始化新传奇的进一步消息的问题,您可以创建另一种消息类型,以区分某人何时开始输入关于客户的内容,然后键入其他内容

类似的东西:

public class ClientTypedSomethingElseAboutCustomer 
{
    int CustomerId {get;set;}
    ...
}

然后你的传奇看起来像这样:

public class CustomerSaga : Saga<CustomerSagaData>, IAmStartedByMessages<ClientTypedSomethingAboutCustomer>
    ,IHandleMessages<ClientTypedSomethingElseAboutCustomer>
{
    public override void ConfigureHowToFindSaga()
    {
        ConfigureMapping<ClientTypedSomethingAboutCustomer>
            (message => message.CustomerId).ToSaga(saga => saga.CustomerId);

        ConfigureMapping<ClientTypedSomethingElseAboutCustomer>
            (message => message.CustomerId).ToSaga(saga => saga.CustomerId);
    }
    ...
}

这将确保有关客户的所有消息都将路由到单个saga实例。

通过在单线程模式下运行NServiceBus,可以实现一种近似的排队行为。这可能会限制为客户创建并发传闻,但我不想依赖于此。

答案 1 :(得分:0)

@janpieter_z和@ tom-redfern都是正确的:确保您可以将saga映射到某种客户ID。

你也可以实现complex saga finding logic来找到与正在传入的信息相对应的正确传奇。

此外,如果多条消息没有以正确的顺序到达,则可以将其设置为“IAmStartedByMessages”。

最后,谁将消息发送给您的传奇?传奇不应该负责发送收集数据的请求吗?也许每10秒通过超时或其他东西,直到几分钟没有收到任何东西,或者处理程序回复不同的消息?