-
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
Highland v3.0.0 #179
Comments
Ref #176. |
@vqvu thanks for creating the branch. I haven't had time to zoom into it before the holiday season. That could be on the new year's resolutions ;-) happy holidays ! |
@LewisJEllis I am not sure @vqvu has had time to look into this over the holiday season. I think that the changes needed to flatten the stack are still up for discovery. Last time @vqvu mentioned it he said he had no idea how convoluted this could get. I unfortunately could not find time to look deeply at the new branch. If you feel like diving into it, it would be great and @vqvu will certainly appreciate to be able to discuss potential solutions with someone. I was planning on working on the merge issue #133. @vqvu has rewritten merge in 3.0.0 but, from my understanding, this has nothing to do with the new engine. So I would like to take his new implementation and adapt it to have it meet #133's requirements. This way we will be able to remove this from the 3.0.0 branch. After this, we should make sure that 3.0.0 and 2.x are in sync feature wise (I have seen a few commits that need to be checked) If possible, we should have strictly the same tests between 2.x and 3.0.0 |
I haven't had time to do any work on Highland for the last few weeks... @LewisJEllis I'm happy to discuss ideas on how iterative resume/redirect would be done. We also need some sort of a "memory leak checker" and better performance testing. Also the back-prop stuff (this is pretty useful behavior that's not at all implemented) and |
I modified the PR for merge on #133 ; if @vqvu and @LewisJEllis you have time to review it we could remove the merge refactoring from 3.0.0 |
@LewisJEllis would it make sense to backport ESLint from 3.0.0 to 2.x ? I understand that caolan was ok for the change and don't see a reason to wait for 3.0.0 on this. |
Yes, definitely. I originally did only 3.0.0 because I didn't want to make all the silly little changes twice, and because I wasn't sure how much would be done on 2.x in the meantime. It's now evident that 2.x needs it too, and a couple regexes did most of the work anyway, so I'll go ahead and backport it. That should also help avoid silly conflicts when 3.0.0 lands. Regarding keeping 2.x and 3.0.0 in sync as mentioned in #189 - most things being done on 2.x in the meantime shouldn't cause any major conflicts, so I think an occasional rebase should work just fine. I'll try rebasing 3.0.0 onto master after I backport the linting stuff. I'm not too familiar with |
ok thanks. We'll have to agree with @vqvu and the 'rebase or not rebase'. I'm all for removing
from the 3.0.0 potential conflict footprint. I can't say for sure but I think that it will take some time before we get approval from caolan on 3.0.0 so we'd better not freeze 2.x in the meantime and have an easy workflow for merging/rebasing and later have a clean merge from 3.0.0 to master. |
@jeromew Why was this issue closed? As for "rebase vs merge", I suppose it doesn't really matter too much if we don't expect non-collaborators to contribute. Only issue is that if we start getting a large-ish number of commits on 3.0, it'll start getting more annoying and error-prone to do rebases. That said, I haven't actually tried to do the rebase yet, so maybe this is a non-issue. Agreed that 2.x should still be the branch that gets all back-compat improvements for now. |
Oops sorry my mistake. I thought I was closing the issue regarding ESLint. |
@vqvu maybe we could :
It is always a pain when there are 2 active branches but we did not have a choice here given the surface area of the refactoring. do you see other things that can be backported without breaking back-compat on 2.x ? (eslint and merge is done) |
There's also a few uses of I think these can all be cleanly backported to 2.x. |
Same thing with |
@vqvu I backported I tried to backport |
@vqvu, @LewisJEllis - I propose that we bump the master version to 2.3.0 and then rebase/merge/recreate the 3.0.0 branch what do you think ? |
Sounds good, since most/all of the backporting is done, and 2.x needs a bump anyway. As for whether to rebase or merge - the difference isn't very significant, but I think it comes down to how we want to land 3.0.0. If we want to have a single giant pull request to merge into master, I think rebase should keep that cleaner (although merge probably also works). If we want to eventually just swap the 3.0.0 branch in for master, merge will theoretically keep more information in the history. I've always used rebase in this sort of situation, so I can't comment as well on the merge option. |
Agreed with the 2.x version bump. We can rebase this time to get rid of the backported transforms. I just didn't want to have to rebase every time we add new features to the 2.x branch. I think I know why |
@caolan, for info, I just bumped the highland npm version to 2.3.0 |
thanks @jeromew, I'm hoping to get some time to look at the engine changes in more depth soon too |
@vqvu do you want to try to rebase 3.0.0 or else I might try do it next week. |
Yes, I will do it this weekend. |
Done. Slightly painful cause of the eslint changes, but it wasn't too bad. |
@vqvu thanks. I started digging into it a little trying to see if I could find some performance booster (only using bench.js) There are 3 things that I tried at this stage:
it seems that in the 2.x version, the 'sync' path is even shorter which is probably why it seems to get a better bench than lodash on the 1M test. do you have the same results ? (just to make sure that we can compare things on our respective setups) |
For the try-catch problem - assuming we want to keep them - would using the trick in the Bluebird performance optimisations document help? https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#2-unsupported-syntax
Depending on the performance improvement it could be overkill. |
@svozza the function tryCatch(fn, x) {
try {
return fn(x);
}
catch(e) {
return new StreamError(e);
}
} and then doing in the loop var fnRes;
fnRes = tryCatch(f, x);
if (_._isStreamError(fnRes)) {
push(fnRes);
} else {
push(null, fnRes);
} with this modification + the one on inlining ConsumeStream, the 1M bench.js is on par between lodash and highland on my machine. the try/catch inside the highland loop has a penalty. |
@vqvu do you have a test somewhere regarding the stack exhaustion problem ? |
@LewisJEllis Do you mind if I port your changes from #166 to the 3.0.0 branch? |
Well, I think the reason we didn't do this in 2.x was because it would be a breaking change but I think we still want to do it. #240 was related because |
Right, okay. I do recall the decision not to merge it on 2.x, but I'm otherwise not too sure what the situation is. I left a comment on #191. |
@svozza Why is #191 necessary when you can just use I see a checkbox in the original post about merging in #191 (which I added), but I wasn't thinking about #240 at the time. Edit: To clarify. My thinking was that |
Well I'm not pushed but it's hardly inconceivable that a user might not read the docs and pipe a Highland stream into another one and if the price of us preventing a strange crash for one of those users is just a simple |
The standard behavior of |
Yep, sounds good to me. |
I'll make a PR. |
I'm interested in spending some time soon to help push 3.0 out; @vqvu and @quarterto can you give some guidance on what's left to do that I can help with? The todo at the top seems pretty up-to-date, but I haven't been following closely enough to know exactly what each task entails. Happy to help with docs, testing, and any low- to medium-hanging fruit. Also, is breaking things down into a stream engine core + |
We have:
stream.onDestroy(cb)
.transform(...)
.destroy();
// assert that cb was called. for all transforms. This is more of a problem for transforms (listed in the todo) that return a stream created with
var s = _([1, 2, 3]);
var s1 = s.fork().take(2);
var s2 = s.fork();
s1.each(_.log);
s2.each(_.log);
// => 1
// => 1
// => 2
// => 2
// => 3
I'd like to get this done for 3.0, but we'd want to do this last, since the code movement would make it much harder to merge in the PRs that were applied to 2.x. |
@vqvu I saw your mention of 3.0 here - #388 (comment) and realize that bugfixing 2.x engine bugs are a bummer since many things are automatically fixed in the work you did on 3.x. I think that the engine fixes + the The main drawback as I understand it would be on performance where we would lose some throughput (I don't have numbers on the last version) but the fixes in the engine + the extensibility would help the community and @vqvu has already shown that there was a way to unroll his engine to gain more speed at the expense of readability of the code. Regarding speed, I noted one of the remarks of @caolan :
What is the state-of-affairs is regarding integration of If we strip down the functions, i would rather call it
@vqvu how can we help towards the release of 3.0 ? |
Agreed. The hold up is more me (and I suspect the rest of the collaborators too) not having time to work on this rather than any real blocking issue. @quarterto had a good suggestion to release a 3.0.0-beta1 to npm while we work on finalizing the release, and I think that's a good idea.
We currently only have integration with transducers, and while I don't have hard numbers, I suspect using transducers for sync transforms is faster than using highland directly. Transducers could very well be our answer to the sync problem. I'm not sure about integrations with libraries like lodash. I don't see a way to integrate with them beyond this little snippet. stream.batch(some_reasonable_number)
.flatMap(function (array) {
// use lodash here to turn array into result.
return _(result);
}); At this point, sync performance isn't that bad compared to 2.x, so I'm not too concerned about it. My opinion is that while we should of course care about sync performance the utility of Highland is more about sequencing async computations than raw throughput. Ramda integration is kind of stalled at the moment, but I think it's more about allowing people to leverage their library of transforms, and especially the FP programming style that comes with it, rather than performance. The integrations that was being proposed did not have to do with performance. As it relates to the 3.0.0 release, I can't think of any further breaking changes that we might need to make to make to support ramda integration, so I think we're safe to proceed here. Unless someone things otherwise?
The Here's a question for you and the rest of the collaborators. How do we want to handle the multi-module situation? Do we simply package the modules with highland proper? Or is it worth it to create a highland organization to house the different modules in different repos? Bundling everything up would be the simplest, but I think that would defeat the purpose of spliting up the transforms into basic and non-basic packages. If the user is going to download them all anyway, they might as well be allowed to use them by default.
I think my previous comment here is a good list of the things still pending. They're all boring documentation/testing tasks, which explains why they've been stalled for so long. Also, if you or someone else with npm access can release the current 3.0.0 branch as I'd like to refactor |
What exactly is involved in this task:
I should be able to look at it tomorrow. |
Basically, given an infinite stream var i = 0;
var s = _(function generator(push, next) {
push(null, i++);
next();
});
s.onDestroy(function destructor1() {
})
.through(_.someTransform(...))
.onDestroy(function destructor2() {
})
.take(1)
.resume();
Many transforms get this behavior for free when they use |
Cool. I'll have a go at this tomorrow evening. Btw, I think the idea of creating an organisation and having the various modules in different repos is a great idea. |
I did register the org highland-js a while back... |
@caolan would that make sense for you to migrate highland to an highlandjs org ? I don't know if you have followed the work on extensibility that was done by @quarterto and @vqvu in #337 but a lot of modules could exist in this framework. |
So, I was having a look at this:
And it looks like the destroyed |
Backpressure for forks is managed by When forks want data, they call Forks may be added or removed while the The problem here is that the multiplexer uses Fix in #411. |
Makes sense. Thanks for the explanation! |
This issue tracks any changes we want for v3.0.0. See the 3.0.0 branch.
The biggest change for now is a reimplementation of the Highland engine. See the original PR at #175.
Breaking changes
fork
afterconsume
. Must callfork
at the start.consume
a stream twice.stream.source
no longer exists.pipe
passes along errors if piping to a Highland stream instead of callingthis.emit('error')
(Modifies pipe to pass along highland errors #166).See Reconsider making mappingHint's default mapper wrap in an array. #360 (comment)wrapCallback
and stream constructor passes an array for the default mapping hint when there are more than one argument is passed to the callback (Implement mappingHint for wrapCallback, fixes #246 #247, hintMapper default mapper should return array when more than one arg #335).zipAll
renamed tozipEach
.zipAll0
renamed tozipAll
.reduce
andscan
argument order reversedmap
will now throw an error if the argument is not a function. The old behavior instead mapped all stream elements to the argument if it was not a function.Before release
onDestroy
(see back-propagation of _.nil #172)consumes
without a fork.consume
-based should get this for free, but not all transforms useconsume
. Maybe we should add acreateDownstream
method that does this for us.noValueOnError
to test the backpropagation behavior.Makepipe
pass along errors to a Highland stream (Modifies pipe to pass along highland errors #166).pipe
docs pointing tothrough
for the case when users want to pipe along errors as well as values to another Highland stream (Highland v3.0.0 #179 (comment)).ConsumeStream
andPipelineWrapperStream
(to make it easier to port Extensibility 3.0 #337).ConsumerStream
PipelineWrapperStream
use
(see Extensibility 3.0 #337).noValueOnError
to test that core transforms always return an object of the appropriate extended type.use
.Fix default mapping hint behavior (hintMapper default mapper should return array when more than one arg #335).Remove the note in the docs that say we are changing the default behavior.reduce
andscan
zipAll
andzipAll0
pickBy
map
throw an error if not given a function (Map shouldn't accept a value. Move that to value() #404).highland-2
module for reverting the transform rename/reargs (Highland v3.0.0 #179 (comment))index.js
intohighland/core
andhighland/transforms
Nice to have but can be delayed until after release
consume
and redirect.The text was updated successfully, but these errors were encountered: