0

I have two pieces of code s.t.
- one produces stream of sets of active alerts in the system.
- second consumes events of raise/fall of an alert.

assuming the first part produces the following stream
["a", "b"],
["c"],
["e", "f", "g"],
I want to push these as
("a", True),
("b", True),
("c", True),
("a", False),
("b", False),
("e", True),
("f", True),
("g", True),
("c", False).
to the second part of the system.

I can do the following

events=[["a", "b"], ["c"], ["e", "f", "g"]]
alerts = Observable\
            .from_(events)\
            .map(lambda x : set(x))\
            .scan(lambda (prev, events), curr : (curr, {(i, True)  for i in curr - prev}.union(\
                                                       {(i, False) for i in prev - curr})),\
                  (set(), set()))\
            .map(lambda (prev, events) : events)

subject = rx.subjects.Subject()

def my_flatten(set):
    for x in set:
        subject.on_next(x)

subject.subscribe(lambda x : print(x))

alerts.subscribe(my_flatten)

which produces the following result, which is ok

('a', True)
('b', True)
('b', False)
('a', False)
('c', True)
('c', False)
('g', True)
('e', True)
('f', True)

But I hoped to have a solution without a subject, something like the following

events=[["a", "b"], ["c"], ["e", "f", "g"]]

alerts = Observable\
            .from_(events)\
            .map(lambda x : set(x))\
            .scan(lambda (prev, events), curr : (curr, {(i, True)  for i in curr - prev}.union(\
                                                       {(i, False) for i in prev - curr})),\
                  (set(), set()))\
            .flat_map(lambda (prev, events) : events)
alerts.subscribe(lambda x : print(x))

alerts = Observable\ .from_(events)\ .map(lambda x : set(x))\ .scan(lambda (prev, events), curr : (curr, {(i, True) for i in curr - prev}.union({(i, False) for i in prev - curr})), (set(), set()))\ .map(lambda (prev, events) : events)

but it produces the following, which is incorrect because you cannot reconstruct active events from it, c turns to be active at the end.

('a', True)
('b', True)
('b', False)
('a', False)
('c', False)
('c', True)
('g', True)
('e', True)
('f', True)

flat_map does not preserve the order, do you think there is another solution?

Thank you,
Michael

  • It's hard to make this into a robust streaming solution without weakening the conditions, because what if a value is dropped, or you're working with real values: how long will you wait for the "next" element? Could you elaborate on your application? – concat Feb 26 '18 at 14:37
  • question edited. – Michael Rolnik Feb 27 '18 at 07:42
  • Your foremost problem is that _sets_ themselves are unordered. You can't rely on your first solution either to enforce any ordering. – concat Feb 27 '18 at 16:10

0 Answers0