There are a bunch of ways of doing this based on what you really want. It's not clear from your question exactly what the condition is.
I'm going to take the view that you want to track multiple ContextId
at the same time for the situation when an .Topic == "a"
appears followed by the next value for that ContextId
by a .Topic == "b"
. This means that any number of message for other ContextId
values could appear between the two messages. If this is not the case please let me know.
var query =
messages
.GroupBy(x => x.ContextId)
.Select(xs =>
xs
.Publish(ys =>
ys
.Where(y => y.Topic == "A")
.Select(y =>
ys
.Where(w => w.Topic == "B")
.TakeUntil(ys.Where(w => w.Topic != "B")))
.Switch()))
.Merge();
My test data is:
messages.OnNext(new Message() { ContextId = "1", Topic = "A" });
messages.OnNext(new Message() { ContextId = "2", Topic = "B" });
messages.OnNext(new Message() { ContextId = "3", Topic = "C" });
messages.OnNext(new Message() { ContextId = "2", Topic = "A" });
messages.OnNext(new Message() { ContextId = "1", Topic = "B" });
messages.OnNext(new Message() { ContextId = "2", Topic = "C" });
messages.OnNext(new Message() { ContextId = "2", Topic = "B" });
From which I get one value only Message() { ContextId = "1", Topic = "B" }
.
As far as memory is concerned then this will eventually use up all of the memory on the computer if enough ContextId
values appear. Of course it must. But the only way to know how much is to measure it in your code.
Remember, once you call .Dispose()
on the subscription you get your memory back.