-
Notifications
You must be signed in to change notification settings - Fork 23
Back pressure #25
Comments
Streams do support backpressure (with highWaterMark) — although I didn't get it to work (= the data just flows) and I currently don't have much time to investigate further. For this to work we have to introduce some kind of function whose call blocks the component. Using Promise.coroutine() and yield would look as follows:
My implementation of
The call to The problem is that we introduce yet another ugly 'yield' statement. 'yield' makes perfect sense when reading, but I don't like its appearance when sending. |
In cFBP is back-pressure considered "advisory" (i.e. to prevent processes from being overwhelmed with IPs), or is strict/immediate back-pressure feedback necessary for correctness? I ask because my implementation using Node streams (https://github.com/tlrobinson/sbp discussed in #14) currently supports back-pressure, but suffers from the problem you mentioned in another issue where it takes ~N writes for back pressure to be communicated up an N-deep pipeline of streams (https://github.com/dominictarr/pull-stream#transparent-backpressure--laziness). If a few extra IPs aren't a problem this isn't a big deal, otherwise it is. |
Also, I don't consider requiring |
@ComFreek Your implementation makes a lot of sense! Thanks for the pointers. I was trying to get more ideas as to how this could possibly be done. And I agree with @tlrobinson that the @tlrobinson To my knowledge back-pressure is pretty important and not advisory. It's one of the main issues @jpaulm has with noflo. There are scenarios where you need strict back-pressure. An example would be a loop-type network, where you have interdependence between two or more processes. Not sure how a stream would behave in that setup though as I haven't tried using streams that way. |
@kenhkan If that's the case then "pull" type streams are the only way to connect ports, right? How are processes distributed across OS processes or physical machines/networks? Does a "receive" essentially send a blocking request (RPC?) for the next IP to the upstream process? Are there any example/documented network protocols for cFBP implementations? I think that would help clarify it a bit for me. |
@tlrobinson I'm not sure actually, as I'm in the exploratory phase as well. All I know is that what Paul envisions as "push" is like a process "pushing" control flow to its neighbors when IPs are moved, be it upstream or downstream. Say, Distributed FBP I believe would be some kind of TCP-like setup. Matt who worked on a Tcl implementation of FBP has each process as a separate OS-level process and communicate via TCP sockets. Blocking is achieved with SYNs and ACKs. The upside of his setup is of course instant distributability given that it's using the internet protocol already. For documentation on any pre-existing network protocol, @jpaulm would be the best person to answer. |
By "pull" I mean the downstream processes need to explicitly tell the upstream processes whenever they can accept another IP, e.x. "ok now you can give me a single IP" vs. "ok now you can give me IPs until I tell you to stop". Or perhaps if a connection has a capacity >1 it can say "ok now you can give me up to X number of IPs, until I tell you I you can give me more" (similar to TCP windows). Either way would require explicit acks of some kind, to continually tell upstream processes how many IPs they're allowed to send. That's why I was curious about any existing FBP network protocols. |
Got it. That makes sense. It sounds like your second approach is more fundamentally sound. And yes, I'm pretty sure for FBP semantics to work you'd need explicit acks. @jpaulm Any insight on a network protocol for FBP? |
FWIW, almost 50 years ago, we discovered that acks and naks are not My Socket implementations (not Web Sockets) on JavaFBP and C#FBP are Lastly I believe @jonnor has done the most work on protocols... Regards, Paul
|
Is FBP duplex at all? When you say |
No, I was thinking of a network where some of the links are running on full Also I'm not totally comfortable with the terminology "B tells A" - B
|
@tlrobinson @ComFreek
I've been trying to tackle back pressure in my fork, and I must say I'm hitting a dead-end and it'd be nice to hear your thoughts on this.
Take a look at this gist. Replace the content of
recvr.js
on @ComFreek 's fork and runfbptest01.js
. You should see something similar to this. The timing doesn't matter, but (correct me if I'm wrong please @jpaulm ) the copier should stop after the 5th copy is sent, because of a capacity of 5 set on the connetion between copier and recvr.I know that @ComFreek might not have gotten to that point in his fork. Me neither. But the issue is that it seems to be rather difficult in JS (at least with ES5 as that was my thesis).
With generators, the control flow is inverted here so there doesn't seem to be an obvious way to have the callee of yield to suspend, or continue to suspend, the caller (in this case, the FBP process). In this particular case,
yield
is returned a bluebird promise butPromise.coroutine()
would continue the generator as soon asreceive
settles, which it must do. I haven't put too much thought into this problem in a streams-based solution, but I suspect that it's a similar situation.Any idea on this problem?
The text was updated successfully, but these errors were encountered: