Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ public override Task<DocumentServiceLease> CreateLeaseIfNotExistAsync(
Mode = this.GetChangeFeedMode()
};

this.requestOptionsFactory.AddPartitionKeyIfNeeded((string pk) => documentServiceLease.LeasePartitionKey = pk, Guid.NewGuid().ToString());
// Use the lease document id as the partition-key value so that retries / concurrent
// creates for the same lease resolve to the same (id, partitionKey) tuple. This lets the
// Cosmos per-partition-key id-uniqueness check turn duplicates into a 409 Conflict
// instead of silently persisting cross-partition-key duplicates.
this.requestOptionsFactory.AddPartitionKeyIfNeeded((string pk) => documentServiceLease.LeasePartitionKey = pk, leaseDocId);

return this.TryCreateDocumentServiceLeaseAsync(documentServiceLease);
}
Expand All @@ -153,7 +157,11 @@ public override Task<DocumentServiceLease> CreateLeaseIfNotExistAsync(
Mode = this.GetChangeFeedMode()
};

this.requestOptionsFactory.AddPartitionKeyIfNeeded((string pk) => documentServiceLease.LeasePartitionKey = pk, Guid.NewGuid().ToString());
// Use the lease document id as the partition-key value so that retries / concurrent
// creates for the same lease resolve to the same (id, partitionKey) tuple. This lets the
// Cosmos per-partition-key id-uniqueness check turn duplicates into a 409 Conflict
// instead of silently persisting cross-partition-key duplicates.
this.requestOptionsFactory.AddPartitionKeyIfNeeded((string pk) => documentServiceLease.LeasePartitionKey = pk, leaseDocId);

return this.TryCreateDocumentServiceLeaseAsync(documentServiceLease);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,13 @@ private static void ValidateRequestOptionsFactory(RequestOptionsFactory requestO
else if (requestOptionsFactory is PartitionedByPartitionKeyCollectionRequestOptionsFactory)
{
Assert.IsNotNull(lease.PartitionKey);

// The lease's partition-key value must equal its id so that concurrent/retry creates
// for the same lease resolve to the same (id, partitionKey) tuple and Cosmos's per-
// partition-key id-uniqueness check turns duplicates into a 409 Conflict. Using a
// random Guid here would silently persist cross-partition-key duplicates and stall
// the change feed load balancer. See DocumentServiceLeaseManagerCosmos.CreateLeaseIfNotExistAsync.
Assert.AreEqual(lease.Id, lease.PartitionKey);
}
else
{
Expand Down
Loading