dat-ecosystem-archive / datproject-discussions

a repo for discussions and other non-code organizing stuff [ DEPRECATED - More info on active projects and modules at https://dat-ecosystem.org/ ]
65 stars 6 forks source link

Investigating message abstraction layer implementation options #64

Open aschrijver opened 6 years ago

aschrijver commented 6 years ago

(NOTE This showcase is part 2b of Positioning, vision and future direction of the Dat Project)

Before reading on: These are just initial thoughts, any feedback is greatly appreciated!

Options

The preferred approach currently is to leave hypercore alone and write the message abstraction layer on top of it. Presumably biggest concern here is:

I haven't worked with protocol-buffers, but looking at definition of schema.proto in hypercore-protocol and holding that against the vert.x approach to messaging, I see following options:

  1. Frames only, with existing messages redefined as Frame Types 1a. Only a subset of existing messages are actual Frame Types
  2. Just add a single Message message to existing ones defined
  3. Don't touch hypercore-protocol, hypercore, implement on top of them

1. Everything is a Frame

In this setup:

Impact (first impression):

Pro's:

Cons:

The schema.proto may look something like this:

// add package name to discern from the old format that must still be supported for a while

package hypercore.proto.messaging

// or keep original messages at root level, retain backwards compatibility with one .proto
// alternatively the old specification format can be imported

message Fragment {
    // type=0, should be the first message sent on a channel
    message Feed { ... }

    // type=1, overall connection handshake. should be send just after the feed message on the first channel only
    message Handshake { ... }

    // type=2, message indicating state changes etc.
    message Info { ... }

    // type=3, what do we have?
    message Have { .., }

    // type=4, what did we lose?
    message Unhave { ... }

    // type=5, what do we want? remote should start sending have messages in this range
    message Want { ... }

    // type=6, what don't we want anymore?
    message Unwant { ... }

    // type=7, ask for data
    message Request { ... }

    // type=8, cancel a request
    message Cancel { ... }

    // type=9, get some data
    message Data { ... }

    enum FrameType {
        Feed = 0;    // the first message, also default enum value
        Handshake = 1;
        Info = 2;
        Have = 3;
        Unhave = 4;
        Want = 5;
        Unwant = 6;
        Request = 7;
        Cancel = 8;
        Data = 9;
    }

    required FrameType type;

    // either define a single header format, or support multiple alternatives in 'oneof' construct, e.g.
    //
    // - DatDefaultHeaderFormat (default format holding only dat-supported attributes)
    // - KeyValueHeaderFormat (user-extensible map of header attributes)
    // - CustomHeaderFormat (e.g. community-contributed JsonSchemaHF, JsonLdHF, etc.)

    message Header { ... }

    // probably include some more Frame fields here

    // the body payload that depends on the frame type
    oneof Body {
        Feed = 0;
        Handshake = 1;
        Info = 2;
        Have = 3;
        Unhave = 4;
        Want = 5;
        Unwant = 6;
        Request = 7;
        Cancel = 8;
        Data = 9;    // maybe rename to Message, or Payload
    }
}

Notes:

1a - Some Frame Types, some message types

Option 1 may be a very naive design, as it assumes all current message types are natural candidate Frame Types, however:

  1. Some (or all) might be implemented as message types instead using frame type Data
    • E.g. Handshake, Info, Cancel
  2. Maybe some (or all) are not suitable to serve as frame type

Looking at vert.x messaging they only have 4 types:

Looking at this, vert.x slices it completely different than current hypercore-protocol I need more time studying Dat inner-workings to say anything sensible here, your feedback can help!

First thoughts:

[TODO What would be missing if adopting the vert.x way with only the 4 frame types?]

Impact:

Pro's / Con's:

Add a Message to the mix

In this option the schema stays as it is now, with the only additional a Message message type. The message would have a Header and Body and some other fields, just like Frame

Pro's / Con's / Impact:

3 - Layered on top of hypercore

Currently this option is favoured by both @mafintosh and @joehand But to me this seems to be the approach with most downsides

In this setup:

Pro's:

Cons:

--

Previous part: Design of message-based abstraction layer on top of hypercore

Next part: Optimizing traction and exposure