flatMapLatest – add next observable before removing previous
See original GitHub issueIn AbstractPool
there is an option drop
that is used by flatMapLatest()
, when drop
is set to old
then the old source is unplugged from the pool before the next source is added:
/* snip */
} else if (this._drop === 'old') {
this._removeOldest();
this._add(obj, toObs);
}
/* snip */
https://github.com/rpominov/kefir/blob/master/src/many-sources/abstract-pool.js#L37
Is there a strong opinion against either a) adding another option, perhaps overlapping
, to softly drop the old stream (add the next stream before removing the eldest) or b) making the default behavior for old
add the next stream before removing the old stream.
Option (b) seems perhaps a little risky and a breaking change. But having control over this would be beneficial in some cases where you are switching between streams, but don’t want them to deactivate it unless they are unused in the next streams activation chain.
Example:
const channelA = Kefir.stream((emitter) => {
console.log('connect a');
let count = 0, id = setInterval(() => emitter.value(count++), 250);
return () => { console.log('disconnect a'); clearInterval(id); };
});
const channelB = Kefir.stream((emitter) => {
console.log('connect b');
let count = 0, id = setInterval(() => emitter.value(count++), 250);
return () => { console.log('disconnect b'); clearInterval(id); };
});
const data = {
a: channelA,
b: Kefir.combine([channelA, channelB]),
c: channelB,
};
Kefir.sequentially(1000, ['a', 'b', 'c', undefined])
.flatMapLatest(p => p ? data[p] : Kefir.never())
.log('result');
Console:
> connect a
> result <value> 0
> result <value> 1
> result <value> 2
> disconnect a
> connect a
> connect b
> result <value> [0, 0]
> result <value> [1, 0]
> result <value> [1, 1]
> result <value> [2, 1]
> result <value> [2, 2]
> disconnect a
> disconnect b
> connect b
> result <value> 0
> result <value> 1
> result <value> 2
> disconnect b
> result <end>
Notice how both a
and b
disconnect and immediately reconnect on the swap. What, I think, I would like in some situations:
> connect a
> result <value> 0
> result <value> 1
> result <value> 2
> connect b
> result <value> [3, 0]
> result <value> [3, 1]
> result <value> [4, 1]
> result <value> [4, 2]
> disconnect a
> result <value> 3
> result <value> 4
> result <value> 5
> disconnect b
> result <end>
Is there a different way to achieve this behavior without having to alter the behavior of AbstractPool
. In my real use case, these Kefir.stream()
observables wrap over a socket.io connection, so it’s less-than-ideal to tear down the connection between sibling projections, but at the same time, its less-than-ideal to keep the socket going for unused/unneeded projections.
Issue Analytics
- State:
- Created 7 years ago
- Comments:5 (3 by maintainers)
That’s what I was thinking as well. I’ll make a pull request soon with a potential implementation. Thanks!
I’ve implemented this on https://github.com/kefirjs/kefir/pull/320, please have a look when you have a chance. The console output is slightly different but that’s correct IMO as the intervals inside each stream are different.