Dot net client - upsert async for a list has odd behaviour on remote server

Hi,

I’m experiencing a very odd behaviour while trying to upsert a list of documents on a server.
I’m sending on a batch that coutains twice the same document, but updating the version.

Code is something like this

        var values = new List<MyEntity>();
        // created 50 mocked distinct objects
        var list = MockedDataBuilder.GetMockedData(50);

        // forcing to generate 2 versions of the same document
        for (var i = 1; i <= 30; i++) {
            list.ForEach(x => {
                x.Version = i;
                values.Add(x);

                var clone = x.Clone();
                clone.Version = 1000 + i;
                values.Add(clone);
            });
        }
        // building documents
        var bucket = ClusterHelper.GetBucket(_cfg.Bucket);
        var documents = values.Select(obj => {
            var ret = (IDocument<T>) new Document<T> {
                Id = obj.Id.ToString(),
                Content = obj
            };
            return ret;
        }).ToList();

        // sending batch to the server
        var task = bucket.UpsertAsync(documents, TimeSpan.FromSeconds(10));
        task.Wait();

Testing on a couchbase server installed on my machine I always get the following result
Query
select version, count(1)
from dev-bucket
where type in [‘myentity’]
group by version

Result
[
{
“$1”: 100,
“version”: 1030
}
]

But when I run this code on a couchbase server on a remote machine it get a few documents with older versions

[
{
“$1”: 89,
“version”: 1030
},
{
“$1”: 11,
“version”: 30
}
]

I’ve checked the server logs on the documents that are on version 30 and I can see all of them had 60 updates, which is correct, so no failures on the commands.

My question is, does the method UpsertAsync on the dot net client ensures the order of the records on the list ? I could not figure out why it always keeps the order running the code on my machine and it always mixes the order when it runs on a remote server.

Hi,

The SDK will send your list of upsert requests in the order specified, but there is no guarantee that they will reach your CB server in the same order. This is just the nature of sending operations over a network. This is why you see your Upserts sometimes happening ‘out-of-order’. You should not do multiple asynchronous operations to the same document and expect them to happen sequentially. A solution is to await your first ‘version’ upserts, then do another batch for your next version.

Hope this helps,
Will

PS: You may also be interested in Transactions which guarantees the order (amongst many other things), within a transaction: https://docs.couchbase.com/java-sdk/3.0/howtos/distributed-acid-transactions-from-the-sdk.html (though not yet available for .NET SDK).

2 Likes