You are reading content from Scuttlebutt
@cryptix %LmqKf4lB513hCTotX8A06lbuwXS35BYBWU29STMx0DA=.sha256
Re: %1ts45jTyl

That being said, when I started out working on EBT, I told myself: "you know luigi is a bad plumber but if you want to get this done you will have to squint and ignore it. Making it proper will be much simpler once there the structure and tests are done." right?! well... This worked for a couple of weeks until I glued the parts together and started sending actually messages.

Due to a fluke in duplex mode, I couldn't get the raw bytes out of a duplex stream and since the crappy message format is really strict, it's impossible to validate once the JSON system turned it into map[string]interface{} (which is the default for an object with unknown fields).

It was this shitty hand that made me finally re-think the luigi abstractions and set out to write go-muxrpc v2 which doesn't use it, working branch wario. At it's core, it replaces luigi sink and source with ByteSink and ByteSource.

So where before you did this to read from a luigi source:

// method name and a type-hint (other args ommitted for clearity)
src, err := muxrpc.Source("createHistoryStream", theActualType{}, ...)
// handle err

for {
  // ctx is for timeout control (like if the connection goes away)
  v, err := src.Next(ctx)
  if luigi.IsEOS(err) { break }

  // we told the client what type we want the results as buttt
  // dictated by luigi.Source, the return from Next is always interface{}
  // so we need to runtime-assert it before it can be used
  msg, ok := v.(theActualType)
}

With a ByteSource you get a Next function and a normal reader.

// method name and expected result encoding flag
src, err := muxv2.Source("createHistoryStream", TypeJSON, args)
// handle err

for src.Next(ctx) {
    var a theActualType
    err = src.Reader(func(r io.Reader) error {
        // decode into the variable a
        return json.NewDecoder(r).Decode(&a)
    })
    // handle err

    // 1) you can now directly use the value without any assertion madness

    // 2) it's possible to re-use the buffer that is read into between the loop calls!

    // this also works if you don't care about allocations
    // pktBody, err := src.Bytes()
}

Similarly, a ByteSink just gives you a io.Writer and you need to know if you want to fill it with JSON or what ever.

It's more explicit, yes but it doesn't treat you like it knows whats best and then only goes half the way.

Realizing these problems was my christmas this year. Having converted most of go-ssb to this new API now, I really like where it's at. It's hard to pinpoint a single example. The brave might poke into the commits of my current WIP branch.

User has not chosen to be hosted publicly
Join Scuttlebutt now