使用ReplaySubject将事件添加到Rx observable的开头 - 可能吗?

时间:2012-05-12 02:43:39

标签: system.reactive event-sourcing

我正在使用Rx(反应式框架)实现总线,到目前为止它看起来不错。我现在面临的问题是如何在流开始之前添加事件。

为了提供更多上下文,这是针对事件源(la CQRS / ES)。当总线启动时,许多用户获得 IObservable 。此时,总线询问用户他们需要从哪个事件编号/序列开始。事件从磁盘加载,从最低编号开始并添加到流中,每个订阅者使用where语句从正确的事件开始。随着应用程序的运行,新事件将被添加并转发给订阅者。这部分效果很好。

有些订阅者迟到,但仍需要所有活动。只要事件数量足够小,看起来 ReplaySubject 就符合要求。我想我可以做一些磁盘/离线缓存来保持更多它们(任何指针欢迎!)。

更大的问题是,当某些订阅者获得IObservable时,他们需要获取在最初加载的事件之前发生的事件。如下情况。

当公共汽车开始时它加载了事件#50(最早的人想要)。现在,新订阅者请求IObservable,除了他们需要从#20开始。所以我想要做的是加载20-49,并在流的开始之前添加它们。现有订户都不应该看到任何事件(它将由Where过滤)。

看起来这应该是可能的,但我无法理解它。这在Rx中可能吗?如果是这样,怎么样?

谢谢! 埃里克

2 个答案:

答案 0 :(得分:3)

我会以一种非常简单的Rx方式来看待它。不要使用ReplaySubject,对所有“实时”事件使用单个Subject,并为每个订阅者汇总前面的历史事件。

我想你可能有某种数据结构来跟踪历史记录。如果你已经加载/捕获#50中的事件已经在内存中说#80,那么当一个新用户出现请求来自#20的事件时,我会做这样的事情:

var fromIndex = 20;
var eventSubject = new Subject<Event>();
capturedEvents
    .GetFromIndex(fromIndex) // Gets a enumerable list of events
    .ToObservable()
    .Concat(eventSubject)
    .Subscribe( ... );

然后您可以使用eventSubject来捕获新事件,如下所示:

eventSubject.Subscribe(capturedEvents.CaptureEvent);

这是否符合您的需求?

答案 1 :(得分:2)

如何:

itemsFromTwentyToFourtyNine.Concat(currentItems);