Skip to content

Commit 7c839ff

Browse files
committed
NCBC-4068: Recent failures in txns
Motivation ========== Transactions regressions need a quick look Motification ============ Recently, the new (in 8.0) SubdocAccessDeleted flag was supported. This means we can access deleted documents using replica reads. But this was a bit mixed with the ordinary 'CreateAsDeleted' capability that we have always used for transactions to create tombstone docs when inserting and so on. What we need to do is only set the AccessDeleted flag to true on replica reads if the server supports it. Small change to do so. Also renamed it SubdocAccessDeleted for some disambiguation. Results ======= Transactions fails now gone. Change-Id: Ie407fd6ac78da602a5b870b59a46bab4b29ca33b Reviewed-on: https://review.couchbase.org/c/couchbase-net-client/+/234627 Reviewed-by: Michael Reiche <michael.reiche@couchbase.com> Tested-by: Build Bot <build@couchbase.com>
1 parent 4b19ef5 commit 7c839ff

5 files changed

Lines changed: 18 additions & 13 deletions

File tree

src/Couchbase/KeyValue/CouchbaseCollection.cs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ internal CouchbaseCollection(BucketBase bucket, IOperationConfigurator operation
7272

7373
if (_bucket is CouchbaseBucket couchBucket)
7474
{
75-
AccessDeleted = couchBucket.CurrentConfig?.BucketCapabilities.Contains(BucketCapabilities
75+
SubdocAccessDeleted = couchBucket.CurrentConfig?.BucketCapabilities.Contains(BucketCapabilities
7676
.SUBDOC_ACCESS_DELETED) == true;
7777
}
7878
}
@@ -100,7 +100,7 @@ internal CouchbaseCollection(BucketBase bucket, IOperationConfigurator operation
100100
public bool IsDefaultCollection { get; }
101101

102102
/// <inheritdoc />
103-
public bool AccessDeleted { get; }
103+
public bool SubdocAccessDeleted { get; }
104104

105105
#region KV Range Scan
106106

@@ -954,14 +954,22 @@ private async Task<MultiLookup<byte[]>> ExecuteLookupIn(string id, IEnumerable<L
954954
}
955955
});
956956
}
957+
// if we are a replica read _and_ wanting access deleted, we have to be sure to
958+
// check that AccessDeleted is "fully" supported...
959+
var docFlags = options.AccessDeleted ? SubdocDocFlags.AccessDeleted : SubdocDocFlags.None;
960+
docFlags |= options.ReplicaIndex.HasValue ? SubdocDocFlags.ReplicaRead : SubdocDocFlags.None;
961+
if (options is { AccessDeleted: true, ReplicaIndex: not null } && !SubdocAccessDeleted)
962+
{
963+
docFlags &= ~SubdocDocFlags.AccessDeleted;
964+
}
957965

958966
var lookup = new MultiLookup<byte[]>(id, specs, options.ReplicaIndex)
959967
{
960968
Cid = Cid,
961969
BucketName = _bucket.Name,
962970
CName = Name,
963971
SName = ScopeName,
964-
DocFlags = options.AccessDeleted && AccessDeleted ? SubdocDocFlags.AccessDeleted : (options.ReplicaIndex.HasValue ? SubdocDocFlags.ReplicaRead : SubdocDocFlags.None),
972+
DocFlags = docFlags,
965973
Span = span,
966974
PreferReturns = options.PreferReturn,
967975
};
@@ -1021,10 +1029,7 @@ public async Task<IMutateInResult> MutateInAsync(string id, IEnumerable<MutateIn
10211029
docFlags |= SubdocDocFlags.InsertDocument;
10221030
break;
10231031
case StoreSemantics.AccessDeleted:
1024-
if (AccessDeleted)
1025-
{
1026-
docFlags |= SubdocDocFlags.AccessDeleted;
1027-
}
1032+
docFlags |= SubdocDocFlags.AccessDeleted;
10281033
break;
10291034
default:
10301035
throw new ArgumentOutOfRangeException();
@@ -1045,7 +1050,7 @@ public async Task<IMutateInResult> MutateInAsync(string id, IEnumerable<MutateIn
10451050
docFlags |= SubdocDocFlags.ReviveDocument | SubdocDocFlags.AccessDeleted;
10461051
}
10471052

1048-
if (options.AccessDeletedValue && AccessDeleted) docFlags |= SubdocDocFlags.AccessDeleted;
1053+
if (options.AccessDeletedValue ) docFlags |= SubdocDocFlags.AccessDeleted;
10491054

10501055
using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.Kv.MutateIn, options.RequestSpanValue);
10511056
using var mutation = new MultiMutation<byte[]>(id, specs)

src/Couchbase/KeyValue/ICouchbaseCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public interface ICouchbaseCollection
4242
/// <summary>
4343
/// Returns true if the bucket supports accessDeleted.
4444
/// </summary>
45-
public bool AccessDeleted { get; }
45+
public bool SubdocAccessDeleted { get; }
4646

4747
#region Basic
4848

src/Couchbase/Stellar/KeyValue/StellarCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public StellarCollection(string collectionName, StellarScope stellarScope, Stell
7676

7777
public bool IsDefaultCollection { get; }
7878

79-
public bool AccessDeleted => false;
79+
public bool SubdocAccessDeleted => false;
8080

8181
public ICollectionQueryIndexManager QueryIndexes => _stellarCollectionQueryIndexes;
8282

tests/Couchbase.Transactions.Tests.UnitTests/Mocks/MockCollection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Couchbase.Transactions.Tests.UnitTests.Mocks
1414
internal class MockCollection : ICouchbaseCollection
1515
{
1616
public Dictionary<string, TransactionGetResult> AllDocs { get; }
17-
public bool AccessDeleted => false;
17+
public bool SubdocAccessDeleted => false;
1818
public MockCollection(IEnumerable<TransactionGetResult> mockDocs)
1919
{
2020
AllDocs = mockDocs.ToDictionary(o => o.Id);
@@ -170,7 +170,7 @@ public MockCollectionWithNames(string collectionName, string scopeName, string b
170170

171171
public uint? Cid => throw new NotImplementedException();
172172

173-
public bool AccessDeleted => false;
173+
public bool SubdocAccessDeleted => false;
174174

175175
public string Name { get; }
176176

tests/Couchbase.UnitTests/Core/Diagnostics/Tracing/Fakes/FakeCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public FakeCollection(string name, IScope scope, IBucket bucket, ClusterOptions
3030
public IScope Scope { get; }
3131
public IBinaryCollection Binary { get; } = null!;
3232
public bool IsDefaultCollection => Scope.IsDefaultScope && Name == "_default";
33-
public bool AccessDeleted => false;
33+
public bool SubdocAccessDeleted => false;
3434

3535
public Task<IGetResult> GetAsync(string id, GetOptions? options = null)
3636
{

0 commit comments

Comments
 (0)