couchbase / go-couchbase

Couchbase client in Go
https://godoc.org/github.com/couchbase/go-couchbase
MIT License
321 stars 92 forks source link

Incr operation failing sometimes #52

Open taseppa opened 9 years ago

taseppa commented 9 years ago

In my testcase I increment a counter three times in a row using:

value, err := bucket.Incr(key, amount, amount, 0)

When the bucket has been recently destroyed one of the 3 Incr operations (not necessary the first operation) quite often fails with :

MCResponse status=NOT_STORED, opcode=INCREMENT, opaque=0, msg: Not stored

Any idea what could cause this?

taseppa commented 9 years ago

Here is a testcase, I seem to be able to reproduce the problem everytime given that there is no existing document with such key. The main thing here is that the document is updated concurrently. Sorry about the formatting.


package main

import (
    "time"
    "runtime"
    "fmt"
    "log"
    "github.com/couchbase/go-couchbase"
)

func IncrementCounter(bucket *couchbase.Bucket, key string, amount uint64) {

        fmt.Printf("Trying to increment counter, key=%s, amount=%d\n", key, amount)

        value, err := bucket.Incr(key, amount, amount, 0)

        if err != nil {
                fmt.Printf("Error happened while incrementing %s\n", err)
    } else {

                fmt.Printf("Incremented counter, new value=%d\n", value)
    }
}

func main() {

    runtime.GOMAXPROCS(runtime.NumCPU())

    c, err := couchbase.Connect("http://localhost:8091/")
    if err != nil {
        log.Fatalf("Error connecting:  %v", err)
    }

    pool, err := c.GetPool("default")
    if err != nil {
        log.Fatalf("Error getting pool:  %v", err)
    }

    bucket, err := pool.GetBucket("default")
    if err != nil {
        log.Fatalf("Error getting bucket:  %v", err)
    }

    go IncrementCounter(bucket, "12345", 2)
    go IncrementCounter(bucket, "12345", 2)
    go IncrementCounter(bucket, "12345", 2)

    time.Sleep(10000000)
}
tleyden commented 9 years ago

When the bucket has been recently destroyed

Can you elaborate on that?

taseppa commented 9 years ago

Sorry I meant when the document has been destroyed. And it doesn't matter if it has been recently destroyed, the important part is it doesn't exist prior to running that testcase.

taseppa commented 9 years ago

I tried to replicate the testcase with github.com/couchbaselabs/gocb but everything works fine.

Any thoughts about the maturity of gocb versus this repo?

maniktaneja commented 9 years ago

I'll take a look at this. Please give me a day's time. Cheers !

maniktaneja commented 9 years ago

gocb is not certified yet for production environments. I tried using your test case and I don't see the problem

Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6 Greywind-2:incr manik$ ./incr Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Trying to increment counter, key=12345, amount=2 Incremented counter, new value=2 Incremented counter, new value=4 Incremented counter, new value=6

taseppa commented 9 years ago

Hm, interesting. Did you try to run the testcase exactly as it it is? The line runtime.GOMAXPROCS(runtime.NumCPU()) is particularly important, without that I can't reproduce the error either.

maniktaneja commented 9 years ago

With one change. I added a line to delete the key "12345" before it tries to increment the value. It works even without that but i have to manually delete the key between successive invocations.

package main
import (
    "fmt"
    "github.com/couchbase/go-couchbase"
    "log"
    "runtime"
    "time"
)

func IncrementCounter(bucket *couchbase.Bucket, key string, amount uint64) {

    fmt.Printf("Trying to increment counter, key=%s, amount=%d\n", key, amount)

    value, err := bucket.Incr(key, amount, amount, 0)

    if err != nil {
        fmt.Printf("Error happened while incrementing %s\n", err)
    } else {

        fmt.Printf("Incremented counter, new value=%d\n", value)
    }
}

func main() {

    runtime.GOMAXPROCS(runtime.NumCPU())

    c, err := couchbase.Connect("http://localhost:9000/")
    if err != nil {
        log.Fatalf("Error connecting:  %v", err)
    }

    pool, err := c.GetPool("default")
    if err != nil {
        log.Fatalf("Error getting pool:  %v", err)
    }

    bucket, err := pool.GetBucket("default")
    if err != nil {
        log.Fatalf("Error getting bucket:  %v", err)
    }

    bucket.Delete("12345")

    go IncrementCounter(bucket, "12345", 2)
    go IncrementCounter(bucket, "12345", 2)
    go IncrementCounter(bucket, "12345", 2)

    time.Sleep(10000000)
}