Skip to content

Conversation

@torcolvin
Copy link
Collaborator

[4.0.3 backport] CBG-4949: Prevent Excessive conflict logging

cherry-pick of b8b689b

Copilot AI review requested due to automatic review settings January 16, 2026 16:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR backports a fix to prevent excessive conflict logging by optimizing the conflict detection workflow. The change reduces redundant conflict checks by caching the result of rev tree conflict detection when performed earlier in the process.

Changes:

  • Added parameters to track whether a rev tree conflict check has already been performed and its result
  • Modified IsInConflict to accept and use cached conflict check results, avoiding duplicate processing
  • Updated conflict handling logic to reuse cached results when available

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
db/document.go Added parameters to IsInConflict function to accept cached rev tree conflict check results and skip redundant checks
db/crud.go Introduced tracking variables for rev tree conflict checks and passed cached results to IsInConflict to prevent duplicate logging

Comment on lines 1495 to 1508
// we need to check if local CV version was generated from a revID if so we need to perform conflict check on rev tree history
if doc.HLV.HasRevEncodedCV() {
_, _, isConflictErr := db.revTreeConflictCheck(ctx, putOpts.RevTreeHistory, doc, putOpts.NewDoc.Deleted)
if isConflictErr != nil {
return HLVConflict
if revTreeConflictCheck {
if revTreeConflictCheckStatus {
return HLVConflict
} else {
return HLVNoConflict
}
} else {
_, _, isConflictErr := db.revTreeConflictCheck(ctx, putOpts.RevTreeHistory, doc, putOpts.NewDoc.Deleted)
if isConflictErr != nil {
return HLVConflict
}
}
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested if-else structure can be simplified using early returns. Consider checking !revTreeConflictCheck first and returning early, then handle the revTreeConflictCheckStatus check. This improves readability and reduces nesting depth.

Suggested change
// we need to check if local CV version was generated from a revID if so we need to perform conflict check on rev tree history
if doc.HLV.HasRevEncodedCV() {
_, _, isConflictErr := db.revTreeConflictCheck(ctx, putOpts.RevTreeHistory, doc, putOpts.NewDoc.Deleted)
if isConflictErr != nil {
return HLVConflict
if revTreeConflictCheck {
if revTreeConflictCheckStatus {
return HLVConflict
} else {
return HLVNoConflict
}
} else {
_, _, isConflictErr := db.revTreeConflictCheck(ctx, putOpts.RevTreeHistory, doc, putOpts.NewDoc.Deleted)
if isConflictErr != nil {
return HLVConflict
}
}
// We need to check if the local CV version was generated from a revID. If so, perform a conflict check on rev tree history.
if doc.HLV.HasRevEncodedCV() {
if !revTreeConflictCheck {
_, _, isConflictErr := db.revTreeConflictCheck(ctx, putOpts.RevTreeHistory, doc, putOpts.NewDoc.Deleted)
if isConflictErr != nil {
return HLVConflict
}
return HLVNoConflict
}
if revTreeConflictCheckStatus {
return HLVConflict
}

Copilot uses AI. Check for mistakes.
Comment on lines +1437 to 1443
base.DebugfCtx(ctx, base.KeyCRUD, "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history", base.UD(doc.ID))
return nil, nil, false, nil, base.HTTPErrorf(http.StatusConflict, "Document revision conflict")
}

parent, currentRevIndex, err := db.revTreeConflictCheck(ctx, opts.RevTreeHistory, doc, opts.NewDoc.Deleted)
if err != nil {
base.DebugfCtx(ctx, base.KeyCRUD, "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history", base.UD(doc.ID))
Copy link

Copilot AI Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The duplicate log message at lines 1437 and 1443 uses identical wording for two different scenarios: cached conflict check result vs. new conflict check result. Consider differentiating these messages to make debugging clearer, such as 'conflict previously detected' vs. 'conflict detected' to indicate whether the result came from cache.

Suggested change
base.DebugfCtx(ctx, base.KeyCRUD, "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history", base.UD(doc.ID))
return nil, nil, false, nil, base.HTTPErrorf(http.StatusConflict, "Document revision conflict")
}
parent, currentRevIndex, err := db.revTreeConflictCheck(ctx, opts.RevTreeHistory, doc, opts.NewDoc.Deleted)
if err != nil {
base.DebugfCtx(ctx, base.KeyCRUD, "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history", base.UD(doc.ID))
base.DebugfCtx(ctx, base.KeyCRUD, "conflict previously detected between the two HLV's for doc %s, and conflict previously found in rev tree history (using cached result)", base.UD(doc.ID))
return nil, nil, false, nil, base.HTTPErrorf(http.StatusConflict, "Document revision conflict")
}
parent, currentRevIndex, err := db.revTreeConflictCheck(ctx, opts.RevTreeHistory, doc, opts.NewDoc.Deleted)
if err != nil {
base.DebugfCtx(ctx, base.KeyCRUD, "conflict detected between the two HLV's for doc %s, and conflict found in rev tree history during rev tree conflict check", base.UD(doc.ID))

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants