-
Notifications
You must be signed in to change notification settings - Fork 23
jsfbp that doesn't use fibers? #14
Comments
Also, I would argue that this is incorrect:
(http://www.jpaulmorrison.com/fbp/software.html#JSFBP) A full Node.js environment could be emulated in the browser (and indeed "browserify" attempts to do this), but node-fibers can't be easily emulated in the browser because it introduces "blocking" semantics (something similar can be implemented once ES6 generators are available, though: https://stackoverflow.com/questions/18293563/can-node-fibers-be-implemented-using-es6-generators) |
Honestly I can't see how an API that looks like JavaFBP and other classical implementations could be made with traditional Javascript. If you can find a way please tell. This kind of api:
Blocking is not a problem but a feature, and I'm not really convinced that generators can emulate this behavior. I hope it does though, I simply couldn't find a reasonable way. |
Here's a simple example (using the Bluebird promise library and ES6 generators, available in iojs and recent versions of node with the "--harmony" flag) (obviously
|
Hi @tlrobinson, I wrote http://www.jpaulmorrison.com/fbp/noflo.html As you may be aware, I have been working with classical FBP for 40+ years, Around Christmas, my son suggested I look at return and yield, and, while I did not see another approach that was as promising, and in fact, using I agree that node-fibers is a bit further away from plain JS than nodejs, If people are willing to add nodejs to basic Javascript, I fail to see why We have used back pressure, selective receive, and information packets with
Best regards, and many thanks, Paul M. On Feb 11, 2015 5:40 PM, "Tom Robinson" [email protected] wrote:
|
That's why I suggested to use an abstraction layer in issue #13. Such an abstraction layer would ideally allow us to switch between different implementations, e.g. one for Node.js and another one for browsers. Another big and related advantage is that the implementation for browsers could only emulate Fibers, so that jsfbp is ready to run in browsers even though not with full performance. |
This is simply not going to happen. AFAIK there has been zero serious discussion of adding fibers to the browser, and even if that started happening it would be many years before they were implemented and widely available. Compare that to ES6's generators, which are built into current versions of Node.js, in the next version of JavaScript, so likely to start showing up in browsers soon. As you can see from my example above, you can get you something pretty similar to fibers. It's possible there's some reason why you can't implement classical FBP with generators instead of fibers, but I don't know yet (note that Bruno also mentioned generators and preprocessors like Streamline.js as a solution to callback hell) |
Could you try making a prototype that achieves a functionality equivalent 2015-02-12 13:26 GMT-03:00 Tom Robinson [email protected]:
|
If you can find a way to simulate multiple stacks in JS, then we should be
|
Can Collate be written in the current version of JSFBP (using fibers)? |
Absolutely! The structure and even coding would be very similar to https://github.com/jpaulm/jsfbp/blob/master/components/rrmerge.js - you just have to add the "low tag" logic (output the IP with the lowest tag value, and then do a 'receive' from the input array port element that that IP came from). Historically, Collate also adds open and close brackets to the output stream - this function could be packaged as a separate component, but it uses the same control fields as Collate, so it seemed practical to combine the two functions. |
In my quest to understand collate I implemented a version without brackets here: #17 I'll work on proof-of-concept with generators/promises/streams next. |
@jpaulm @alfa256 Here's a proof-of-concept using Streams, Promises, and ES6 Generators via Blubird's It may be difficult to understand if you're not very familiar with JavaScript and "promises" or "streams", but the relevant thing to note is I've implemented collate without using Fibers. Note that
Note that I'm using Streams in "paused mode" (http://nodejs.org/api/stream.html)
I've added a receive method to readable streams which returns a promise. You can use the promise directly (as I do in I think basing a FBP system on Streams would be powerful because you can implement a component in whichever style makes the most sense. From the outside it doesn't matter. For example, Streams also support "backpressure" so they can communicate to their upstream processes when they do or don't want more data: http://nodejs.org/api/stream.html#stream_event_drain Also note that I'm using streams in "object mode" http://nodejs.org/api/stream.html#stream_object_mode but normal mode might be interesting in some cases. |
So from what I can see the api changes would be adding a yield to 2015-02-17 16:47 GMT-03:00 Tom Robinson [email protected]:
|
@alfa256 I don't believe Note that the only code in my proof of concept that's aware of generator functions or |
Hi! Interested bystander here. I just finished reading the fbp book, and this jsfbp project excites me. For what it's worth, I would like to second the motion for using streams. Streams have a large "following" (node, gulp, etc) and are relatively well understood even by pedestrian js developers like myself. I share @tlrobinson's concern that node-fibers are off-putting. Streams, on the other hand, I can rally behind. Plus they are available in the browser today with a choice of packages, and hopefully native support soon. Of course, there may exist very good reasons against using streams here, but my current (admittedly limited) understanding does not see any. https://highlandjs.org/ |
The proof of concepts look _promis_ing! I have finished my changes which separate all Network-related thing from those related to (Fiber-)Runtime.
Admittedly, the last two methods seem to still heavily rely on Fibers. I will look into their use cases and investigate. I have read that Promise implementations might tend to create memory leaks (just search for "Promises memory leak" or "Promises garbage collection"). This is especially related to unresolved promises and/or errors. There is a very long discussion titled Promises/A+ implementations can lead to resource leaks in Node. |
I've expanded my proof-of-concept into a fully functional prototype: https://github.com/tlrobinson/sbp Like the PoC, it uses Streams, as well as a combination of Promises, Generator functions, and Bluebird's I'd be curious to hear from the experts whether they'd consider this true "classical-FBP", and if not, why not? |
Collate1 looks interesting - it seems strange that you can't "hide" the What I am curious about is whether you ran a complete test case, e.g. Collate2 looks much more alien to me - it even seems to have a recursive @brodavi You said, " I share @tlrobinson's concern that node-fibers are Regards, Paul M. @jpaulm https://github.com/jpaulm @alfa256 https://github.com/alfa256 It may be difficult to understand if you're not very familiar with collate1 collate2 Note that I'm using Streams in "paused mode" (
I've added a receive I think basing a FBP system on Streams would be powerful because you can Streams also support "backpressure" so they can communicate to their Also note that I'm using streams in "object mode" — |
@jpaulm It's highly unlikely fibers will be added to browsers. If you don't believe me try asking a few other JavaScript experts. |
@tlrobinson And Streams and Promises are better than Fibers... how?!
Because some JavaScript guru has blessed them...? Just curious!
|
@jpaulm The main thing is with fibers you can't tell if a function call is going to block execution, whereas with generators you explicitly yield within a generator function (that's why the yield can't be hidden) Here's a description of the difference between generators and fibers: https://gist.github.com/creationix/6416266 But the important thing is generators are already in ES6 (the next version of JavaScript), and fibers would be mostly redundant, so they're unlikely to ever make it into the JavaScript spec and therefore browsers. |
I just wrote the following to Comfreek:
I don't want to know whether a function call is going to block execution
|
In JavaScript it has always been safe to assume a function will run to completion before another event fires which could change the state that the function is using. Fibers break that assumption, which is unacceptable to a lot of people, including the people in charge of defining future versions of JavaScript. Generators also break that assumption, but you have to explicitly opt-in by declaring a generator function (with the "function*" syntax) and use the "yield" keyword, so there's no chance of someone else's code deep in some library you're using yielding execution without your knowledge. BTW this article expands on the gist I linked to in my last comment. We can argue about which way is better, but it's not going to change the fact that you're unlikely to ever get fibers in the browser. |
This discussion is interesting, but I feel it should be on the Group, so On Mar 8, 2015 6:01 AM, "Tom Robinson" [email protected] wrote:
"Change the state that the function is using." That's really the whole point of FBP : two functions cannot use the same |
It seems to me that the appropriate place for much of this discussion is PS I would do it, but it would be very difficult using my little tablet!
|
Hi ComFreek, Nice to hear from you - and nice to be back! I am starting to look at JSFBP's derivatives - your streams-impl, and Tom's sbp (streampunk?). BTW Will you be updating your fork's readme to include the instructions you sent me? I think it would be useful. What I find so strange is that these (to my way of thinking) contorted forms are said to seem more natural to a JS user (at least you and Tom seem to be saying this) than the nice simple syntax of the current JSFBP version (much improved by you, I admit!). In the former case, the user has to learn and get comfortable with Promises, Streams, etc., plus FBP, while in the case of basic JSFBP they just have to learn FBP! I also don't see why 'yield' and those asterisks have to be visible - surely making them visible means that it could be meaningful to drop them - what happens if one or both of these are dropped by mistake? Basically, it seems to come down to the fact that you and Tom don't believe that the JS community will accept node-fibers as readily as they have Promises etc. Surely that's just a matter of building a constituency of people who are more interested in getting the job done than in playing with abstruse concepts which probably don't have a well-defined use case anyway! Marcel @laverdet, are you getting any feedback on this? ComFreek and Tom, I think I know where you stand on the issue of node-fibers vs. Promises, etc. - Ken, Alex, Ged, @bjouhier, @JeanHuguesRobert, @laverdet, I would be interested in hearing your views. I am double posting this note here, as I don't have email addresses for some of the people I would appreciate feedback from. FYI The repositories I am looking at are: https://github.com/jpaulm/jsfbp https://github.com/ComFreek/jsfbp/tree/streams-impl https://github.com/tlrobinson/streampunk.js Best regards to all, Paul M. |
Correct, my position is that it is very unlikely that fibers have a future
|
I've also wondered if it would be possible to do this with a FBP wrapper around celery and its canvas primitives. |
node-webworker-threads works on Node 0.10.x and is known to be unstable with 0.12.x and io.js, which I hope to fix in the coming weeks. It is true that |
@ComFreek As always, my questions would be: what language(s) and what operating system(s)? Given the existence of languages which don't play together too well, such as Java and C#, sockets would seem a promising approach... JavaScript seems to be able to talk to C[++], so this suggests that it might be interesting to work with Boost... What did you have in mind? |
fwiw I want to echo what @tlrobinson & @bjouhier said about fibers never making it into browsers or a standard. I started working on fibers in early 2011 when early versions of generators were still being discussed for standardization. We all knew |
@jonnor Thanks for the link, the readme seems very elaborate! Is there any quickstart guide available? I would like to see it in action (e.g. having component A running on my PC and component B on my notebook, both connected to my router). @jpaulm As it is the very idea of the "FBP library", I would target some a wide range of operating systems and programming languages by employing low-level languages, such as C and C++, and common network protocols. I'll have a look at celery, thanks for the link @chadrik. |
@ComFreek we're using it production a couple of places, but still have not landed on final API/protocol - so usage docs are not the priority just yet. Will probably tag & announce first stable in a couple of weeks, when we've migrated everything in the production pipeline to it. For now, see: https://github.com/the-grid/msgflo/blob/master/spec/fixtures/participants.coffee https://github.com/jonnor/imgflo-server/blob/master/src/worker.coffee |
Merci, @laverdet! I think it is becoming obvious that what we really need
|
Cluster and workers both take advantage of cores |
Do you have a link for clusters? Couldn't find anything on Google!
|
First result in Google for "node cluster" |
@jpaulm I encourage you to also take a look at nodejs/node#1159. This is work in progress on io.js but it looks very promising. A pure JS implementation based on a worker library which is blessed by io.js (and hopefully bundled with it some day soon) could be a winner. |
Thanks @bjouhier - sounds interesting!
|
Here is a quote from http://www.jpaulmorrison.com/fbp/noflo.html :
How would these be approached in a fully isolated environment such as that described in nodejs/node#1159 ? |
The same approaches you would use to distribute FBP processes across OS
|
I asked first! :-) And no, I don't know how to do this across OS processes or hosts either. IIRC Matt Lai has something he calls the "traffic cop" which can manage things like back pressure, but I'm not sure how that generalizes across multiple OS's. |
Matt Lai gave a pretty complete description of his approach using Tcl/Tk in his March 19, 2014, post in https://groups.google.com/forum/#!searchin/flow-based-programming/appkata/flow-based-programming/hnst0E6AcUI/6al-uVAKL4oJ . |
Do you mean Hoare? http://spinroot.com/courses/summer/Papers/hoare_1978.pdf |
No, Bradley, it is Dijkstra! See
http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD123.PDF
I can't read it on my tablet but Google found it! I _believe_ this
predates Hoare's CSP.
Regards,
Paul
|
I have just posted a web page about the Concat (Concatenate) component in "classical" FBP and in NoFlo - http://www.jpaulmorrison.com/fbp/concat.html . Comments would be appreciated. Note: we are not sure if the cited Concat.coffee program is up to date. |
What's the consensus on using Node Fibers? My experience with JavaScript and web app's, or hybrid mobile i.e. Cordova/PhoneGap, React Native... which all use JavaScript is that 70-90% of the app's code is client side. So for me JSFBP needs to run in the browser? Does NoFlo run in the browser? What do they do differently from JSFBP to make that happen? |
Electron utilizes chromium multi process architecture http://dev.chromium.org/developers/design-documents/multi-process-architecture by rpc, can this be helpful to use multiple processes? http://electron.atom.io/blog/2016/07/28/electron-internals-node-integration |
Not sure if anyone is still interested in JavaScript implementations of FBP, but I dusted off my streampunk.js project and updated it to use I also implemented the streampunk implements selective receive and back pressure: https://github.com/tlrobinson/streampunk.js/blob/master/test/backpressure.js |
@tlrobinson Thanks for the update. Maybe
One disadvantage is that you definitely give up your "handle of computation", whereas with the Incidentally, I've recently written an |
Hi Tom, this certainly *does* seem much closer to the spirit of classical FBP! I guess one has to specify "await", but it feels very "classical"! I assume JavaScript still can't handle multiple cores though - do you know if this is likely to change any time soon...?
Regards,
Paul
…On Fri, Apr 13, 2018 at 2:43 PM, Tom Robinson ***@***.***> wrote:
Not sure if anyone is still interested in JavaScript implementations of
FBP, but I dusted off my streampunk.js
<https://github.com/tlrobinson/streampunk.js> project and updated it to
use async/await, which is included in ES2017 and supported natively in
node.js and most browsers. AFAIK fibers haven't gained any traction in the
last few years.
I also implemented the concat component: https://github.com/tlrobinson/
streampunk.js/blob/master/components/concat.js As you can see it's about
the same length as jsfbp's concat.
streampunk implements selective receive and back pressure:
https://github.com/tlrobinson/streampunk.js/blob/master/
test/backpressure.js
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#14 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AATGJ8Lah3N90tsCqKafJGNoB1zArqU6ks5toPG5gaJpZM4DfOIf>
.
|
I have been reviewing this very interesting correspondence, and I see that there was a long hiatus after @giantelk 's 2015 query (which apparently wasn't answered), until @emptist 's suggestion in 2017, and @tlrobinson 's update a few days ago. I imagine quite a lot must have changed in the JS world since 2015! Also, since that time I have refined the locking logic in JavaFBP and C#FBP... and it turned out to be a bit more complex than I had thought (I think those two implementations are working now - anyone want to check them?!), so this logic would have to be replicated in a truly asynchronous, multi-core implementation using JS. @giantelk, I confess I didn't quite understand your query, but my guess is that client side doesn't really need multiple cores, although single-core FBP would improve maintainability, so jsfbp could apply here (or I guess @tlrobinson 's latest, since it seems more viable than jsfbp), but server side would definitely benefit from multi-core support - so why not use JavaFBP or C#FBP... which would in addition provide better performance?! And we wouldn't have to twist JS into a pretzel! @tlrobinson are you considering providing tutorial material for streampunk...? Or a successor...? Regards, Paul |
@jpaulm I consider The only (standard) way JavaScript can make use of multiple cores is via Web Workers, but memory is typically copied between them, not shared. There's also a proof-of-concept
By the way, it's worth noting the One other thing I've considered exploring is building |
@tlrobinson I looked at the WHATWG link you gave and I think I saw "chunks". Do I get the impression that Streams has reinvented Objects?! Or did I misunderstand? I can't imagine why JS dropped Objects - unless JS just followed a different evolutionary path from something like C? |
@tlrobinson Thanks for the feedback on streampunk, etc. Please keep us posted on how this area of JS evolves, and to what extent it is converging with classical FBP. Regards, Paul |
Fibers are neat, but the majority of node.js developers don't and won't use them, and they don't work in browsers at all. It would be nice if we could provide a "classical FBP" system that works using standard JavaScript APIs.
Actually, after reading http://www.jpaulmorrison.com/fbp/noflo.html I'm pretty confused about how JSFBP is considered more "classical" than NoFlo. That page suggests the key difference is that NoFlow is single-threaded (because JavaScript is single-threaded) and thus not suitable for CPU-intensive programs, but then admits JSFBP is also single-threaded. So is the main difference actually the synchronous vs asynchronous style of programming?
Selective reading of ports and backpressure can both be accomplished in an asynchronous style. For example, Node-style Streams have
pause
andresume
methods for handling backpressure. The port could buffer up to a fixed number of IPs then callpause
on the stream when the buffer fills up. The port could have aread
method that takes a callback (or returns a promise) which gets called when the next IP is available, and callsresume
on the stream if the buffer is no longer.To take advantage of multiple cores you could use something like WebWorkers, though I think a generic system based on a standard IPC mechanism (e.x. ZeroMQ) and serialization protocol (e.x. Protocol Buffers) would be even cooler, allowing you to write components in any language, or even distribute processes across machines.
But anyway, there are several options for sync and async styles in JavaScript:
Asynchronous style:
callback(err, result)
callbacks. This is my least favorite option, but is still the most popular style in Node.js. I probably wouldn't bother with this.Synchronous style:
await
s on promisesAlso this may be useful relevant reading: https://github.com/kriskowal/gtor
EDIT: task.js is another possibility: http://taskjs.org/
The text was updated successfully, but these errors were encountered: