IBucket fails to Upsert immediately after bucket creation

We discovered a bug with the .Net SDK similar to the following Post;

Steps to reproduce (this is in a single instance of the application):

  1. Using .NetCoreApp 1.1 (Using native dependency injection)

  2. Adding a Singleton to IServiceCollection of ICluster (with necessary configuration)

  3. Adding a Singleton to IServiceCollection of IBucket (with necessary configuration)

  4. Calling IBucket.Upsert() throws the following exception:

    {System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
    at System.ThrowHelper.ThrowKeyNotFoundException()
    at System.Collections.Generic.Dictionary2.get_Item(TKey key) at Couchbase.Core.Buckets.CouchbaseRequestExecuter.<SendWithRetryAsync>d__151.MoveNext()}

  5. Stop the service and restart the service

  6. The same Upsert() with the same document then succeeds

The workaround we came up with is to create and dispose of a Bucket instance immediately:

//our CreateBucketInstance has these two relevant lines of code
var manager = cluster.CreateManager(configuration.ManagementUser, configuration.ManagementPassword);
var createResult = manager.CreateBucket(configuration.BucketName, configuration.BucketSize, saslPassword: configuration.BucketPassword, threadNumber: ThreadNumber.Three, flushEnabled: configuration.FlushEnabled);

using (var newBucket = CreateBucketInstance(configuration, cluster)) { }

In a separate step, a new instance of the Bucket object is instantiated - which is then used to perform the Upsert() and succeeds.

Ideally when a bucket is created it should be able to be used immediately.

@natalie.chalco

Unfortunately, there is a delay while a new bucket is initialized. Configuration needs to be synced between all of the nodes in the cluster, etc. In a situation like this, I’ll normally add a Thread.Sleep after creating the bucket. If I need something more precise, then I monitor this endpoint:

http://one-of-your-nodes:8091/pools/default/buckets

You’ll want to wait until all nodes listed beneath the bucket in question show a status of “healthy”.

Also, I know you didn’t ask about it but I’ll throw in a dependency injection recommendation. I wrote this library for us to use at CenterEdge Software, and shared it publicly. The Couchbase .Net SDK team recently adopted it and are now managing it. It’s the recommended method of performing dependency injection for Couchbase in .Net Core.

Brant

1 Like

There is a JIRA issue tracking a way to make these interfaces easier to program against. See MB-11484 and MB-8504 which I’d opened before that.

1 Like

@natalie.chalco

Thanks for your post and I’m glad @btburnett3 was able to help you regarding timing for creating new buckets.

Another suggestion I would offer is to not use the IBucket instance with a singleton lifestyle. Internally the ICluster instance maintains cached versions of the IBucket instances. Instead you could choose to either use a shorter lifestyle that retrieves an IBucket instance when required, or inject the ICluster and perform an OpenBucket(“bucket-name”).

Thanks

1 Like