Skip to content
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

JRFC 34 - Streamer - A Stream Multiplexing Interface #34

Open
jbenet opened this issue Mar 18, 2015 · 7 comments
Open

JRFC 34 - Streamer - A Stream Multiplexing Interface #34

jbenet opened this issue Mar 18, 2015 · 7 comments

Comments

@jbenet
Copy link
Owner

jbenet commented Mar 18, 2015

Streamer - A Stream Multiplexing Interface

There are many ways to do stream muxing (multiplexing). Many transports offer their own stream multiplexing, for example:

  • SSH
  • QUIC
  • HTTP/2
  • WebRTC

These often differ in how to handle flow control, congestion, priorities, stream hierarchies, and so on. The interfaces different and are often incomplete. They requires knowing much about the specific transport in question, which forces applications to understand the stream muxing library.

This is a great moment to standardize a common API. We should have

  • a standard, cross-platform interface for stream-multiplexors
  • a default implementation that works over any reliable stream (e.g. TCP)
  • native implementation wrappers
  • polyfill for missing features
  • interfaces for both simple streams (no config) and advanced features (priorities, etc)

Links:

@jbenet
Copy link
Owner Author

jbenet commented Mar 18, 2015

@max-mapper
Copy link

in dat we are using https://github.com/maxogden/multiplex

which is a varint length prefixed stream of protocol buffers

e.g. each message is simply:

[varint][protobuf]

where varint is a varint of the length of the protobuf. it's the simplest design we could come up with

@mafintosh
Copy link

The protobuf used in multiplex looks like this:

enum TYPE {
  DATA = 1;
  END = 2;
  ERROR = 3;
  OPEN = 4;
}

message Frame {
  required sint32 channel = 1;
  optional string name = 2;
  optional TYPE type = 3 [default=DATA];
  optional bytes data  = 4;
}

The person instantiating the connection chooses a local channel id and sends that the frame to the remote. If the remote wants to reply with data on the same channel he uses -channel so the when the instantiator receives this frame he can match it to his local channel without there being clashes if both parties use the same channel id for two channels.

Optionally you can set name on the first frame to associate a string name with a channel

@mafintosh
Copy link

Also channel ids can be reused after a channel ends to keep the channel numbers as low as possible

@mafintosh
Copy link

I should note that we designed our multiplex protocol to be as simple as possible (no per channel watermarks etc) since this fits 99% of our use-cases so far.

@max-mapper
Copy link

we might wanna think about doing doing varints in the protobuf style, where we add 3 bits to the end for a 'wire type' ID https://developers.google.com/protocol-buffers/docs/encoding#structure

if we use wire type 2 (length prefixed) then our format would be 100% protobufs all the way down, with this schema describing the outermost container format:

message Stream {
  repeated bytes data = 1;
}

@jbenet
Copy link
Owner Author

jbenet commented Apr 9, 2015

Does it have any flow control? (iirc, no). We need flow control because otherwise sending lots of data makes our data flows starve the control flows (things like dht). We already ran into this :( 

May want to catch up on the discussion @inconshreveable @substack and I were having in #ipfs. I'll find a link and send. The goal is to try and use native streaming as much as possible when present (say on WebRTC, http2, QUIC), mapping with a common interface. But have one library that we can always fall back on if there isn't any native stuff.

Think of it like an abstract-stream-mux module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants