-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix consume and redirect. #175
Conversation
59c8567
to
a486516
Compare
Hmm...looks like some bugs creeped in when I was cleaning up. Ignore this for now. |
6297c77
to
d1c194b
Compare
Ok, fixed. I ran into a weird issue with the |
Wow. |
This involves: - Totally reimplementing stream redirection. - Reimplementing `consume`, `pull`, `fork`, and `resume`. Backward incompatible; - The stream no longer pauses if `next` isn't synchronously called in `consume`, since this is no longer necessary to signal (lack of) demand to the source. - Lots of methods and properties that start with `_` changed (these were private anyway). - The callback for the stream generator and `consume` is guaranteed not to be called a second time until `next` is called. Fixes: - caolan#41 - caolan#141 - caolan#142 - caolan#173
d1c194b
to
16c2145
Compare
Cool ! it's nice to see that you managed to fix all those redirect & pulling bugs. Now this is the kind of commit that everybody fears in a project since it changes so many things. At least the effort that was put in tests make it possible to envision such a change. Maybe we could try and publish one last version based on the current engine before merging this and then start a new major version. I wonder how @caolan would see this go forward. Regarding |
Benefits/risk statement requested by @jeromew in #176. Benefits:
The obvious risk is that the change breaks documented but untested features or that it blows up spectacularly in certain corner cases that aren't being tested for. There's also minor compatibility breaking that would likely require a major version. |
There's a lot to review here, but here's what I've noticed so far:
That said, the code looks nicer. I'm also happy to sacrifice some speed for better predictability / fewer bugs / cleaner code. Are there any easy wins in performance you can find, and do you think you can address the call stack problem? There's a very naive and not particularly important benchmark in the bench directory you can run by doing var _ = require('highland');
var recursiveCounter = function (n) {
return _(function (push, next) {
if (n === 0) {
next(_.nil);
}
else {
setImmediate(function () {
push(null, n);
// log memory usage for every 1k redirects
if (n % 1000 === 0) {
console.log(process.memoryUsage());
}
next(recursiveCounter(n - 1));
});
}
});
};
// initial memory usage
console.log(process.memoryUsage());
recursiveCounter(1000000).each(function (x) {
// do nothing
}); Once the stack issue is resolved and we can run this over a long period of time and check the memory usage then I'd be happy with this change. Preferably there would be some improvements in the sync processing speeds too. |
Just so you know, the original code had a bit of a hack for nested redirects, where it would trim unused intermediaries from the chain. So I have a stream |
The stack overflow is not supposed to happen, so it is certainly fixable. Not sure about performance, but I'll look at it. How are you intending to run it over large periods of time? Do you have some existing code for this? |
I cut sync data processing latency by about 54%. It's not back to where we were, but better. Turns out var fn = s.foo.bind(s); is much slower than var fn = function () { s.foo(); } for critical path functions. |
Ok, ArrayStream case is at roughly perf. parity with underscore. The sync GeneratorStream case is also better. I know why it stack overflows. It's because right now, redirection looks a lot like Is there a good reason to support infinite redirects in this way, considering we don't support infinite I think it's possible to fix; I'm just wondering if it's worth the effort... |
@vqvu congrats on the speed improvement ; regarding the stack usage, the main issue I see is that you can't presume of how people are going to use the library and you don't want it to break unexpectedly on people. Of course it's more easier said than done. I would like highland to be particularly resistant to huge number of values and consume. the way I see it, In this sense, |
Agreed that it would be nice for |
maybe you could 'squash' your commits on this and commit them on a '3.0.0' branch ? From a very rough estimate, I feel like this will need 2 or 3 rountrips of review with @caolan before it is ready to be merged. Maybe it is a good occasion to improve the benchmarks and to create degenerate tests that hit the engine where it hurts. |
Do you mean create a new branch on caolan/highland and put these commits On Thu, Dec 11, 2014 at 2:27 PM, jeromew notifications@github.com wrote:
|
@vqvu yes that is what i meant. It will be easier to collaborate on this if a branch is created. |
I pushed a 3.0.0 branch. Not all commits were squashed, cause I wanted to keep around the development history. A single big commit is not useful for me. Closing this PR in favor of #179, since it's no longer needed. |
Reimplement the stream backend to fix redirect. The old way of doing things was too hard to get right (as evidenced by the number of bugs that we have related to redirect).
This involves:
consume
,pull
,fork
, andresume
.debounce
,throttle
, andlatest
were reimplemented using the public interface instead of private methods.Possible backward incompatibility concerns;
fork
on a stream that has beenconsumed
.next
isn't synchronously called inconsume
, since this is no longer necessary to signal (lack of) demand to the source.consume
is guaranteed not to be called a second time untilnext
is called. Before, you just needed toresume
the stream.Only (1) is even a potential problem I think. Strictly speaking, the API never said you were allowed to
fork
afterconsume
, especially since you were never allowed toconsume
afterfork
.Fixes:
Comments welcome.