varlink / go

Golang implementation of the Varlink protocol
https://godoc.org/github.com/varlink/go/varlink
Apache License 2.0
54 stars 57 forks source link

How do you wait for events as shown in the docs? #5

Open purpleidea opened 5 years ago

purpleidea commented 5 years ago

How do you wait for events as shown in the docs? I can't see anything that take a context, so I'm assuming it's missing or built incorrectly? Eg from the FAQ:

How can I monitor changes or subscribe to signals? Varlink connections can be turned into monitor connections, they are soft-negotiated between the client and the service. The client asks the server to possibly reply with more than one reply, the server replies and indicates that it might have more replies and the client should wait for them.

How do I do this in golang?

Additionally, you might want to change this type of interface:

https://godoc.org/github.com/varlink/go/varlink#Connection.Call

func (c *Connection) Call(method string, parameters interface{}, out_parameters interface{}) error

To something that takes a number of functions that return a param. Eg:

func (c *Connection) Call(method string, in []Param, out []Param) error

func BoolParam(value bool) Param
func IntParam(value bool) Param
func WhateverParam(value bool) Param

HTH

johanbrandhorst commented 4 years ago

You use the varlink.More flag when calling Send to indicate to the server that you want to stream results if they're available. Then call the returned function and check the flags returned:

streamFn, err := x.Send(c, varlink.More, <params>)
if err != nil {
    return nil, err
}
for {
    <data>, flags, err := streamFn()
    if err != nil {
        return nil, err
    }
    // <handle data>
    if flag&varlink.Continues == 0 {
        break
    }
}
purpleidea commented 4 years ago

@johanbrandhorst Apart from this being a particularly non-idiomatic pattern for golang, it still has the above mentioned problem because you're stuck in:

, flags, err := streamFn()

So there's no way to get that to either block until your message is ready OR cause it to unblock if you're tired of waiting... We should be passing in a context somewhere. Please see: https://golang.org/pkg/context/

johanbrandhorst commented 4 years ago

I agree, and I raised an issue with libpod specifically for this case: https://github.com/containers/libpod/issues/4077

johanbrandhorst commented 4 years ago

In practice the libpod implementation seems to respond over the wire every 2 seconds or so, so you don't end up waiting very long, but there really isn't a way to say "I'm done reading, thanks" as far as I can tell. I've been testing the ContainerLogs endpoint streaming, for reference.

haraldh commented 4 years ago

@johanbrandhorst Apart from this being a particularly non-idiomatic pattern for golang, it still has the above mentioned problem because you're stuck in:

, flags, err := streamFn()

So there's no way to get that to either block until your message is ready OR cause it to unblock if you're tired of waiting... We should be passing in a context somewhere. Please see: https://golang.org/pkg/context/

Yeah, we should patch the varlink code for context

haraldh commented 4 years ago

@johanbrandhorst Apart from this being a particularly non-idiomatic pattern for golang, it still has the above mentioned problem because you're stuck in:

, flags, err := streamFn()

So there's no way to get that to either block until your message is ready OR cause it to unblock if you're tired of waiting... We should be passing in a context somewhere. Please see: https://golang.org/pkg/context/

Yeah, we should patch the varlink code for context

Any volunteers?

johanbrandhorst commented 4 years ago

I may look into adding a context.

purpleidea commented 4 years ago

@haraldh AFAICT this isn't fixed yet...

johanbrandhorst commented 4 years ago

Yeah, this should be reopened, the streaming can definitely still be improved.