Skip to content

Instantly share code, notes, and snippets.

@zostay
Last active August 29, 2015 14:26
Show Gist options
  • Save zostay/791c4cc401c18c6883e7 to your computer and use it in GitHub Desktop.
Save zostay/791c4cc401c18c6883e7 to your computer and use it in GitHub Desktop.
P6SGI: Use Supply and/or Channel for streaming?
So after publishing 0.1.Draft of P6SGI, the most prominent feedback I have
received is whether or not Channels are the best option for streaming data. The
main alternative put forward is to use a Supply rather than a Channel. After
carefully weighing the options, I am not sure there is a clear winner in this.
The short answer is, Channel is simpler for app and middleware devs, but may not
scale as well or as easily as a Supply-based solution. On the other hand, there
is no obvious best solution when using a Supply and using a Supply can lead to
lost data if the app and middleware developers are not careful.
Here are the benefits I see of using a Channel.
* A Channel API better describes the problem faced by an app developers when
streaming. It is, in effect, a simple pipe from one process to another. That's
exactly what most apps need.
* Most middleware does not worry about the content of the response. Those that
do can easily pull from the Channel and push to another if they need to.
* A Channel is very safe to use because you can start stuffing before it gets
returned and the server can start receiving as soon as it gets it.
* A Channel is the easiest to explain and demo as well. There are no oddities to
worry about because it is very simple.
The downsides of a Channel are:
* It blocks on the server who is receiving, so either a server needs a thread
dedicated to reading a bunch of channels using earliest/more or a blocked
thread for each. This is not very flexible.
* Each middleware and app must also process their Channel in a separate thread
in a similar way. So Channel may not scale as well.
* Finally, using a Channel as a Supply is possible, but that still does not take
away the limitations already mentioned.
That brings me to the benefits of using a Supply.
* A Supply-based solution is likely going to outperform a Channel, particularly
when scaling. It is a better for the server problem.
* Supply-based workflow is much more flexible, allowing the application,
middleware, and server attack the problem in whatever way seems best to them.
(TIMTOWTDI).
* A Supply is the best fit for the server problem, while being a reasonable fit
for the app and middleware problems.
The downside to Supply comes down to do the fact that all the flexibility
afforded can lead to trouble:
* There is not necessarily a clear best answer to how a Supply-based solution
works. A Supply comes in two main flavors, live and on demand, each with its
own pitfalls.
* If we expect the application to return a Supply, a live Supply is dangerous as
it might be missing data. On the other hand, on demand Supplies might be
tapped twice and get different results each time or even cause side-effects on
each tap, depending on how they are implemented. Servers must then be careful
in how they use the Supply.
* We might instead require the server provide a Supply in the environment, which
is pre-tapped and can be used immediately without these consequences. Is the
user then required to use that Supply? Do they return that Supply? How do
servers deal with a Supply that is filled with data before the app has even
returned the status and header?
Because of all of this, I am considering making more than one built-in streaming
extension. There could be three extension: Channels, app-provided Supply, and
server-provided Supply. Unfortunately, this beings to create a headache for
middleware authors or at least adds complexity to the helper tools needed to
effectively write middleware.
I am at an impasse. Channel is clearly the simplest, but we do not want to limit
performance int he process. Supply is clearly the one that is most flexible and
scales better, but there's a devilish number of details to consider in there
too.
Add to all this that I am somewhat of a Perl 6 noob and may have gotten some of
the issues confused, where am I wrong? What do you think?
Cheers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment