question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Desynchronization downstream of combine

See original GitHub issue

I have an issue where I combine two streams, then make a new object. I then branch from that stream into two others, and it’s important that the values in the two streams must originate from the same object. This has to do with the other libraries I’m using, but I also think it’s the expected and intended behavior. Instead, the two streams end up looking at different objects because they’ve received different signals.

A simple illustration of the problem is below. Note that Math.random() is a stand-in for creating a new object that the signals in streams x and y both must originate from. As an example of why this is important, consider if the object is a new data entity that comes with a randomly-generated UUID; clearly x and y must agree on what that UUID is.

Expected behavior:

  • Both x and y fire every time ab fires.
  • xy emits the value “true”

Actual behavior:

  • ab fires, then only x fires, then ab fires, then only y fires.
  • xy emits the value “false” since x and y received different signals.
    const a = xs.of('a');
    const b = xs.of('b');

    const ab = xs
        .combine(a, b)
        .map(([a, b]) => Math.random())
        .debug('ab');

    const x = ab.map(o => o).debug('x');
    const y = ab.map(o => o).debug('y');

    const xy = xs
        .combine(x, y)
        .map(([x, y]) => x === y)
        .debug('xy');

    xy.addListener({
        next: e => console.log(e)
    });

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:16 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
CarlLethcommented, Aug 4, 2020

So you just should understand how things actually work.

I can rephrase that statement: “So every module of code you write should understand exactly how every stream that gets passed in is constructed, since that will affect its behavior”. That breaks the entire point of abstraction. Say I wrote a function:

function addSeven(x: number) {
  return x + 7;
}

I could reasonably complain if this function sometimes works and sometimes doesn’t, depending on whether x was computed from a multiplication operation instead of addition. And you could come back to me and say: well, of course it works that way, if you just understood how our library works! Multiplication changes the bit-parity of the mantissa in the underlying pseudo-binary representation, and addition doesn’t! Haha, see, you’d understand if you weren’t so stupid!

And I would say: okay, well, this function has no way to check the bit-parity of the mantissa of the pseudo-binary representation, and besides, that’s way outside of the scope of what number is supposed to represent. That’s the definition of a leaky abstraction.

So when I write

function addSeven(numbers: Stream<number>) {
  return numbers.map(x => x +7);
}

and ask: why doesn’t this always work? Why can numbers emit a value that the stream returned by this function never sees? And you come back and say: well of course it works that way, when numbers is downstream of a combine of two streams that are not temporally independent! You’d understand that if you weren’t so stupid!

And I say: okay, well, this function has no way to check if the numbers stream is downstream of a combine of two streams that are not temporally independent, and besides, that’s outside the abstraction of what I thought a Stream was supposed to be.

I understand the technical reasons why it’s occurring in this case. But it is a flaw. It may be a theoretically necessary flaw, one that’s not feasible to fix without causing other problems, and/or one you can work around if you completely change your coding style, but it’s still a flaw. Don’t act like this is some sort of stupid question.

1reaction
wclrcommented, Aug 2, 2020

I belive everthying works as expected.

You can add this:

const ab = xs
  .combine(a, b)
  .map(([a, b]) => Math.random())
  .debug('ab')
  .concat(xs.never())
  .remember()

With this you make ab stream never complete and keep the latest value for the late subscriber y.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The Sync/deSync Model: How a Synchronized Hippocampus ...
Our Sync/deSync model suggests that both the desynchronization of neocortical alpha and the synchronization of hippocampal theta are necessary for successful ...
Read more >
MemoryStream should not forget its last value on complete #310
Desynchronization downstream of combine #309 is directly caused by this behavior. Diamond flow #283 and inconsistency between .of and .
Read more >
Desynchronization and synchronization of central 20-Hz rhythms ...
Request PDF | Desynchronization and synchronization of central 20-Hz rhythms associated with voluntary muscle relaxation: A magnetoencephalographic study ...
Read more >
Desynchronization Traveling Wave Pulse-Coupled-Oscillator ...
b) Downstream-nodes message-reception: Once the message is picked up from its down- stream nj stack, it is then included in the Di general ......
Read more >
Method and apparatus for desynchronization of ... - Justia Patents
The feedback stimulation signal, that is to say the measured, time-delayed and process neural activity, is used as an individual stimulus. In consequence,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found