temporalio / sdk-go

Temporal Go SDK
https://docs.temporal.io/application-development?lang=go
MIT License
481 stars 197 forks source link

Unable to connect to cluster after updating to 1.27.0 #1537

Closed theverything closed 4 days ago

theverything commented 4 days ago

Expected Behavior

When using the go SDK I should be able to connect to the server.

Actual Behavior

When using go SDK version 1.27.0 I get failed reaching server: context deadline exceeded when trying to connect to the server.

Steps to Reproduce the Problem

The sdk version was bumped from 1.26.1 to 1.27.0 in the cli

  1. use the temporal cli @v0.13.0 temporal operator cluster system call succeeds
  2. use the temporal cli @v0.13.1 temporal operator cluster system call fails

Specifications

theverything commented 4 days ago

I didn't see anything in the release notes about min version of temporal server required

Quinn-With-Two-Ns commented 4 days ago

The Go SDK has no minimum version of the server required

Quinn-With-Two-Ns commented 4 days ago

To be clear is the bug report the temporal cli cannot connect to the server or the Go SDK cannot connect?

theverything commented 4 days ago

To be clear is the bug report the temporal cli cannot connect to the server or the Go SDK cannot connect?

Go SDK. The reproduce steps use the temporal cli because it has the same issue.

Quinn-With-Two-Ns commented 4 days ago

Testing temporal v0.13.0 and v0.13.1 I have not issue connecting to my local Temporal server or Temporal Cloud. The Go SDK integration tests also verify connecting against a local server started with docker, a local server started with the CLI and Temporal Cloud. Could you provide some additional details about how you are setting up your server and trying to connect?

theverything commented 4 days ago

Additional context.

We use tls to connect. Here is a basic go program. This works with v1.26.1 and fails with 1.27.0

package main

import (
    "context"
    "crypto/tls"
    "net"

    "go.temporal.io/sdk/client"
)

func main() {
    addr := "temporal-frontend.internal.net:443"
    host, _, err := net.SplitHostPort(addr)
    if err != nil {
        panic(err)
    }

    c, err := client.Dial(client.Options{
        HostPort:  addr,
        Namespace: "default",
        ConnectionOptions: client.ConnectionOptions{
            TLS: &tls.Config{
                MinVersion: tls.VersionTLS12,
                NextProtos: []string{
                    "h2",
                },
                ServerName:         host,
                InsecureSkipVerify: false,
            },
        },
    })
    if err != nil {
        panic(err)
    }

    defer c.Close()

    _, err = c.CheckHealth(context.Background(), &client.CheckHealthRequest{})
    if err != nil {
        panic(err)
    }

    println("SERVING")
}
theverything commented 4 days ago

The equivalent cli command would look like

temporal operator cluster health --address=temporal-frontend.internal.net:443 --tls

Quinn-With-Two-Ns commented 4 days ago

Can you try specifying addr := "passthrough:///temporal-frontend.internal.net:443"

theverything commented 4 days ago

Can you try specifying addr := "passthrough:///temporal-frontend.internal.net:443"

address passthrough:///temporal-frontend.internal.net:443: too many colons in address

theverything commented 4 days ago

Looks like I need to add the passthrough:/// only to the HostPort config key. When I do that it works.

package main

import (
    "context"
    "crypto/tls"
    "fmt"
    "net"

    "go.temporal.io/sdk/client"
)

func main() {
    addr := "axon-temporal-frontend.dna-compute-qa.zg-int.net:443"
    host, _, err := net.SplitHostPort(addr)
    if err != nil {
        panic(err)
    }

    c, err := client.Dial(client.Options{
        HostPort:  fmt.Sprintf("passthrough:///%s", addr),
        Namespace: "default",
        Identity:  "hello-world",
        ConnectionOptions: client.ConnectionOptions{
            TLS: &tls.Config{
                MinVersion: tls.VersionTLS12,
                NextProtos: []string{
                    "h2",
                },
                ServerName:         host,
                InsecureSkipVerify: false,
            },
        },
    })
    if err != nil {
        panic(err)
    }

    defer c.Close()

    _, err = c.CheckHealth(context.Background(), &client.CheckHealthRequest{})
    if err != nil {
        panic(err)
    }

    println("SERVING")
}
Quinn-With-Two-Ns commented 4 days ago

Yes, sorry I missed the line where you are also trying to extract the host name as well.

theverything commented 4 days ago

Is the passthrough:/// documented somewhere?

Quinn-With-Two-Ns commented 4 days ago

Yes it is called out in the release notes

edit: Specifically under Internally call grpc.NewClient instead of grpc.Dial

https://github.com/temporalio/sdk-go/releases/tag/v1.27.0

https://grpc.io/docs/guides/custom-name-resolution/

theverything commented 4 days ago

Thank you for your help @Quinn-With-Two-Ns