1

Google Pubsub's Go binding gets stuck frequently, as explained below. We have been experiencing this problem since a few days ago. To isolate the cause, I wrote a very simple program, as follows, which calls merely Exists() and sees if it returns in a minute:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "time"

    "cloud.google.com/go/pubsub"
    "golang.org/x/net/context"
    "golang.org/x/oauth2/google"
    "golang.org/x/oauth2/jwt"
    "google.golang.org/api/option"
)

func initializeCredential() *jwt.Config {
    keyFile := ...

    jsonKey, err := ioutil.ReadFile(keyFile)
    if err != nil {
        panic(keyFile)
    }

    jwtConfig, err := google.JWTConfigFromJSON(jsonKey, pubsub.ScopePubSub)
    if err != nil {
        panic(jsonKey)
    }

    return jwtConfig
}

func createContext(section string) (context.Context, func()) {
    duration := time.Duration(1) * time.Minute
    ctx, cancel := context.WithTimeout(context.Background(), duration)

    started := time.Now()
    d := func() {
        elapsed := time.Since(started)
        fmt.Printf("%s: elapsed %+v\n", section, elapsed)
        if ctx.Err() == context.DeadlineExceeded {
            fmt.Fprintf(os.Stderr, "deadline exceeded: %s\n", section)
        }
        cancel()
    }
    return ctx, d
}

func newClient(jwtConfig *jwt.Config) *pubsub.Client {
    var opts []option.ClientOption
    if jwtConfig != nil {
        opts = append(opts, option.WithTokenSource(jwtConfig.TokenSource(context.Background())))
    }

    ctx, finalize := createContext("create-client")
    defer finalize()
    client, err := pubsub.NewClient(ctx, "project-id", opts...)
    if err != nil {
        panic("client")
    }
    return client
}

func useSubscription(client *pubsub.Client) {
    ctx, finalize := createContext("use-sub")
    defer finalize()
    subs := client.Subscription("sub-name")
    _, err := subs.Exists(ctx)
    if err != nil {
        panic("subs")
    }
}

func main() {
    jwtConfig := initializeCredential()
    client := newClient(jwtConfig)
    useSubscription(client)
}

Surprisingly, I saw a lot of failures (i.e., `Exists() does not return in a minute). I ran this program 20 times every 2 minutes, and the success ratio is below 50%! I cannot help but think that the Go binding has a bug in it. Has anyone experienced a similar problem?

This program is running under the us-central region of GCP. So, I guess there should not be any network problem.

linjus
  • 149
  • 9

0 Answers0