yarpc / yarpc-go

A message passing platform for Go
MIT License
404 stars 102 forks source link

NewChannelTransport: connTimeout in transportOptions not work #1862

Closed tnclong closed 4 years ago

tnclong commented 4 years ago

https://github.com/yarpc/yarpc-go/blob/dev/transport/tchannel/channel_transport.go#L49

As you can see, connTimeout Not pass to any struct.

If you don't recommend to use connTimeout, Can you give me any suggestion?

peats-bond commented 4 years ago

Hey @tnclong, we recommend using Transport instead of ChannelTransport, which includes this option!

https://github.com/yarpc/yarpc-go/blob/dev/transport/tchannel/transport.go#L107

tnclong commented 4 years ago

@AlexAPB Thanks for your reply. But it works not in expect. I show you a example:

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "go.uber.org/cadence/.gen/go/cadence/workflowserviceclient"
    "go.uber.org/cadence/client"
    "go.uber.org/yarpc"
    "go.uber.org/yarpc/transport/tchannel"
)

func main() {
    trans, err := tchannel.NewTransport(
        tchannel.ServiceName("cadence-client"),
        tchannel.ConnTimeout(3*time.Second),
    )
    if err != nil {
        panic(err)
    }

    log.Println("new transport done")

    dispatcher := yarpc.NewDispatcher(yarpc.Config{
        Name: "cadence-client",
        Outbounds: yarpc.Outbounds{
            // Not able to connect to 127.0.0.1:7932
            "cadence-frontend": {Unary: trans.NewSingleOutbound("127.0.0.1:7932")},
        },
    })
    err = dispatcher.Start()
    if err != nil {
        panic(err)
    }

    log.Println("dispatcher started")

    serviceClient := workflowserviceclient.New(dispatcher.ClientConfig("cadence-frontend"))
    domainClient := client.NewDomainClient(
        serviceClient,
        &client.Options{
            Identity:           "",
            MetricsScope:       nil,
            ContextPropagators: nil,
        },
    )

    log.Println("domain client ok")

    now := time.Now()
    defer func() {
        fmt.Println("conn timeout:", time.Now().Sub(now))
    }()

    // I known context.WithTimeout() able to work but need to pass each methods
    dres, err := domainClient.Describe(context.Background(), "domain-samples")
    if err != nil {
        panic(err)
    }
    fmt.Println(dres)
}

Output:

$ time go run main.go
2019/12/10 14:05:43 new transport done
2019/12/10 14:05:43 dispatcher started
2019/12/10 14:05:43 domain client ok
conn timeout: 59.995128291s
panic: code:unknown message:received unknown error calling service: "cadence-frontend", procedure: "WorkflowService::DescribeDomain", err: dial tcp 127.0.0.1:7932: connect: connection refused

goroutine 1 [running]:
main.main()
    cadence/timeout/main.go:60 +0x611
exit status 2

real    1m1.521s
user    0m1.841s
sys 0m0.754s
peats-bond commented 4 years ago

The connection timeout is used for attempting to connect to the peer. However, we have a default exponential backoff with jitter when trying to connect to peers, so although a connection may fail in the connTimeout period, we retry more than once.

You may disable the backoff by using a None strategy.