Search code examples
gocouchbasesql++gocb

go couchbase (gocb) error - ambiguous timeout or unambiguous timeout


I just getting started with Couchbase in Go, using the library gocb.

Just as a proof of concept trying to query my server for a specific ID and get a result. Here is a modified code sample below.

cOpts := gocb.ClusterOptions{
        Authenticator: gocb.PasswordAuthenticator{
            Username: "user",
            Password: "pw",
        },
    }

    cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
    if err != nil {
        panic(err)
    }

    qOpts := gocb.QueryOptions{}

    // create query
    queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"

    rows, err := cluster.Query(queryStr, &qOpts)
    if err != nil {
        panic(err)
    }

    fmt.Printf("rows: %v\n", rows)

    for rows.Next() {
        var intfc interface{}
        err = rows.Row(&intfc)
        if err != nil {
            panic(err)
        }
        fmt.Printf("interface result: %v\n", intfc)

    }

The couchbase server is on 5.1.

I am either getting...

panic: ambiguous timeout | {"statement":"SELECT * FROM myBucketName WHERE id = '123456789'","client_context_id":"cdd52a06-c7a5-4d3d-8r26-99fg806d559e"}

...when I run the above code.
OR If I put in the following lines after the gocb.Connect(... I get the error that is after that.

err = cluster.WaitUntilReady(25*time.Second, &gocb.WaitUntilReadyOptions{DesiredState: gocb.ClusterStateOnline})
if err != nil {
    panic(err)
}

...error...

panic: unambiguous timeout | {"InnerError":{"InnerError":{"InnerError":{},"Message":"unambiguous timeout"}},"OperationID":"WaitUntilReady","Opaque":"","TimeObserved":25000263891,"RetryReasons":["NOT_READY"],"RetryAttempts":105,"LastDispatchedTo":"","LastDispatchedFrom":"","LastConnectionID":""}  

NOTE: I changed the Username, Password, Server/connStr, bucket, and the id just for example purposes here.

What am I missing here?


Solution

  • Credit to @vsr for the answer.
    All the other responses helped, but nothing worked until after I did that suggestion, adding cluster.Bucket("mybucket") after the connection.

    One thing that was missing is putting in a "Bucket" name. See below...

    In addition to @vsr help and answer, I just found something on the website in the docs about this.
    [https://docs.couchbase.com/go-sdk/current/howtos/n1ql-queries-with-sdk.html](Couchbase Docs) In the Golang example just after getting started, it mentions in the comments of the code that 'For server versions 6.5 or later you do not need to open a bucket here' and then the next line it opens a bucket. Good information.

        cOpts := gocb.ClusterOptions{
            Authenticator: gocb.PasswordAuthenticator{
                Username: "user",
                Password: "pw",
            },
        }
    
        cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
        if err != nil {
            panic(err)
        }
    
        bucketName := "myBucket"
        cluster.Bucket(bucketName)
    
        qOpts := gocb.QueryOptions{}
    
        // create query
        queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"
    
        rows, err := cluster.Query(queryStr, &qOpts)
        if err != nil {
            panic(err)
        }
    
        fmt.Printf("rows: %v\n", rows)
    
        for rows.Next() {
            var intfc interface{}
            err = rows.Row(&intfc)
            if err != nil {
                panic(err)
            }
            fmt.Printf("interface result: %v\n", intfc)
        }
    

    Just adding that cluster.Bucket("myBucket") line made this work.
    The server is old, and is a dev server that has a lack of resources, so I also upped the timeouts knowing that it was going to be slow. I upped the timeouts by adjusted the cluster options (cOpts named in the code) to the following...

        cOpts := gocb.ClusterOptions{
            Authenticator: gocb.PasswordAuthenticator{
                Username: "user",
                Password: "pw",
            },
            TimeoutsConfig: gocb.TimeoutsConfig{
                ConnectTimeout: 95 * time.Second,
                QueryTimeout:   95 * time.Second,
                SearchTimeout:  95 * time.Second,
            },
        }
    

    This would up the timeout to 95 seconds, and I didn't need that much, but the server was slow enough that it was taking 40 seconds in the UI for the same query, so I just wanted to make sure.
    I also adjusted the timeout for the query. I am not sure what the difference is between them, but I adjusted this below.

        qOpts := gocb.QueryOptions{}
        qOpts.Readonly = true
        qOpts.ScanWait = 95 * time.Second
        qOpts.Timeout = 95 * time.Second
    

    Additionally, I am new to couchbase if you couldn't tell, the query was not using an index field. I looked up the indexed fields for that bucket and added it to the query and that more than halved the time.

    EDIT: Using the USE KEYS statement in N1QL seems to be really fast, faster than any query. I adjusted the code so the qryStr query string was like below...

    queryStr := "SELECT * FROM myBucket USE KEYS ['123456789']"