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.

Nested streams not closing

See original GitHub issue

It seems as though streams which are nested using flatMap are not closed out correctly. Code sample:

var most = require('most'),
  jQuery = require('jquery'),
  socket = require('sockjs')('/api/ws'),
  client = require('stomp').over(socket),
  connect = jQuery.Deferred();

client.connect({}, function() {
  connect.resolve();
});

function getResource(resource, headers) {
  return most.fromPromise(connect).flatMap(function() {
    return getSnapshot(resource, headers).flatMap(function(data) {
      return getUpdates(resource, data, headers);
    });
  });
}

function getSnapshot(resource, headers) {
  return stream('/resource/' + resource, headers)
    .take(1);
}

function getUpdates(resource, data, headers) {
  return stream('/topic/' + resource, headers)
    .startWith([])
    .scan(patch, data);
}

function patch(data, patch) {
  return jiff.patch(patch, data);
}

function stream(destination, headers) {
  return most.create(function(add) {
    var subscription = client.subscribe(destination, function(msg) {
      add(JSON.parse(msg.body));
    }, headers);
    return subscription.unsubscribe.bind(subscription);
  })
}

When running code such as:

getResource('resource').take(1).observe(console.log.bind(console));

I expect both streams which are created (getSnapshot and getUpdates) to be disposed of. Currently only the stream generated by getSnapshot is disposed of correctly while the stream generated by getUpdates remains un-disposed.

Issue Analytics

  • State:closed
  • Created 9 years ago
  • Comments:43 (27 by maintainers)

github_iconTop GitHub Comments

1reaction
briancavaliercommented, Oct 21, 2014

Yep, there was a one-character typo in takeWhile that broke dispose. Fixed in 0395555, updated the PR.

rather a long delay between receiving the message in the observe handler and MostJS actually closing the inner stream

Hmmm, I’m not seeing a delay in my test. The dispose function returned from the create callback is invoked very quickly. Quick question: What exactly do you mean by “closing the inner stream”? All most.js can do is call the disposer function (which it seems to be doing quickly in my test) … maybe stompjs’s unsubscribe function takes some time to complete? Is there any more info you can provide on the delay (maybe a timestamped log of some sort) that might help us track it down?

0reactions
briancavaliercommented, Dec 16, 2014

One thing that may help is if we think of join differently (and more correctly). Mechanically speaking, inside the imperative implementation of most.js, there are inner and outer streams being managed by flatMap.

Mathematically speaking however, there are not: the stream named join is a first-order stream containing the string “Inner” at time t = 11 seconds. Any higher-order-ness has been prevented by flatMap.

Hmm… so how would I write it to be as I described?

I think it comes down to what is the larger goal. I’m still not quite sure I have a handle on that, but I’ll try to answer the next question as best I can.

So that join emits an event as soon as outer does?

In the code exactly as it is in the gist right now, there is no way to emit the string “Inner” in 1 second. because “Inner” doesn’t even exist until time t = 11 seconds. If inner immediately emitted “Inner” without setTimeout, it would appear on the console at t = 1 second. Afaict, removing the setTimeout is the only way (barring time travel, of course! 😃 )

Another option would be to use map instead of flatMap. That will, however, emit the inner stream itself (ie the JavaScript object) as an event in join after 1 second, at which point outer will end and be disposed, and the inner stream will never have been started. That doesn’t seem like what you’re after, though.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Correct way to close nested streams and writers in Java
When closing chained streams, you only need to close the outermost stream. Any errors will be propagated up the chain and be caught....
Read more >
Do you have to close all streams of a nested set of streams?
So, one only has to call close on one stream in order to close (and flush, if applicable) an entire series of related...
Read more >
Right way to Close InputStream and OutputStream in Java
Right way of closing stream is by closing them in their own try catch block, so that failure of closing one stream should...
Read more >
Thinking in nested streams with RxJS - Rangle.io
Working with nested data structures. One of my experiments with RxJS was traversing directories of files on my computer and returning a single ......
Read more >
Working with nested JSON using ksqlDB - Confluent Developer
... from a stream of Kafka records that are contained in nested JSON using ksqlDB, ... Start Docker if it's not already running,...
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