Search code examples
gocouchbasedistributed-computing

Couchbase operation has timed out if there is more than one node


I would implement a distributed counter which works well if the couchbase cluster have only one node, but when I add a new one it's return an operation has timed out for every type of operation on the bucket:

type Incrementer struct {
    bucket  *gocb.Bucket
    gap     uint64
    initial int64
    ttl     uint32
}

func New(conn, bucketName, bucketPassword string, gap uint64, initial int64) *Incrementer {
    cluster, err := gocb.Connect(conn)
    if err != nil {
        fmt.Println("ERRROR CONNECTING TO CLUSTER:", err)
        return nil
    }

    // Open Bucket
    bucket, err := cluster.OpenBucket(bucketName, bucketPassword)
    if err != nil {
        fmt.Println("ERRROR OPENING BUCKET:", err)
        return nil
    }

    return &Incrementer{
        bucket:  bucket,
        gap:     gap,
        initial: initial,
    }
}

func (i *Incrementer) Add(key string) error {
    var current interface{}
    cas, err := i.bucket.GetAndLock(key, i.ttl, &current)
    if err == gocb.ErrKeyNotFound {
    _, _, err := i.bucket.Counter(key, 1, i.initial, 0)
    if err != nil {
        return err
    }
    }
    if err != nil {
        return err
    }
    newValue := current.(float64) + 1
    if newValue >= float64(i.gap) {
        newValue = float64(i.initial)
    }
    _, err = i.bucket.Replace(key, newValue, cas, 0)*/

    // https://developer.couchbase.com/documentation/server/3.x/developer/dev-guide-3.0/lock-items.html

    return err
}

Mostly this is the whole code and there is a docker compose as well:

version: "3"
services:
  cb1:
    image: arungupta/couchbase
    deploy:
      replicas: 2
    ports:
      - 8091:8091
      - 8092:8092
      - 8093:8093
      - 8094:8094
      - 11210:11210
    links:
      - cb2

  cb2:
    image: arungupta/couchbase
    deploy:
      replicas: 2

Scenario: When I setup the docker architect there is only one node because I have to add it manually in the Couchbase's UI. That's fine, it's working properly, but when I add the second server with the Add Server button, and try to use it again the Add(key) returns an operation has timed out. I figured out this error comes from the i.bucket.GetAndLock(key, i.ttl, &current) part.

I don't really understand why is it not doing the same as it working when there is only one node.


Solution

  • First, I'd recommend you use the official Couchbase image instead of arungupta/couchbase, since that is not maintained.

    Second, is your Go code running within the docker host? I suspect it is not, and that's the reason you're running into this issue. The Go client needs to be able to reach every Couchbase node. Outside of the docker host, it will only be able to get to one.

    My recommendation is to move your Go client inside of the docker host.