Fatih Mehmet ARSLAN created NIFI-15657:
------------------------------------------

             Summary: AzureDevOpsFlowRegistry: 409 Conflict when multiple flows 
share same branch (monorepo scenario) due to branch HEAD based optimistic 
locking
                 Key: NIFI-15657
                 URL: https://issues.apache.org/jira/browse/NIFI-15657
             Project: Apache NiFi
          Issue Type: Improvement
          Components: Flow Versioning
            Reporter: Fatih Mehmet ARSLAN


h3. Usage Scenario

We are using *AzureDevOpsFlowRegistry* with Apache NiFi in a monorepo-style 
setup.
 * Multiple independent flows exist under the same NiFi root canvas.

 * All flows are versioned into the {*}same Azure DevOps repository, same 
branch, same bucket{*}.

 * We use a single branch (e.g. {{staging}} → {{{}prod{}}}) for version 
promotion.

 * We intentionally avoid per-flow branches to reduce operational overhead, as 
our flows are small and managed by a small team.

This setup works well conceptually, but we are facing consistent {{409 
Conflict}} errors during commit.
h3. Problem Description

When:
 # Flow A commits successfully.

 # Flow B (a completely different flow file in the same repo/bucket/branch) 
attempts to commit.

Flow B fails with:

 

{{409 Conflict}}

Even if:
 * Flow B performs a Pull before committing.

 * The file being committed by Flow B has NOT changed.

 * The last commit affecting Flow B’s file is still the same.

h3. Root Cause

Azure DevOps Push API requires {{refUpdates[].oldObjectId}} to match the 
{*}current branch HEAD{*}.

However:
 * NiFi tracks the {*}file-level last commit id{*}, not the branch HEAD.

 * When Flow A commits, the branch HEAD changes.

 * Flow B still holds the previous commit id (file-level).

 * During push, Azure DevOps rejects the request because branch HEAD no longer 
matches → 409.

This means independent flows inside the same branch interfere with each other, 
even when modifying different files.
h3. Why Separate Branches Is Not Ideal

Using one branch per flow would technically solve this, but:
 * It introduces additional repository and branch management overhead.

 * For small teams managing many small flows, monorepo + single branch is 
operationally simpler.

 * The current behavior makes monorepo usage impractical.

h3. Requested Improvement

We would like to explore alternatives that support monorepo usage without 
requiring separate branches per flow.
h3. Proposed Enhancement (Optimistic Retry at File Level)

On {{{}409 Conflict{}}}:
 # Fetch current branch HEAD.

 # Fetch latest commit affecting the specific file being updated.

 # If the file-level commit has NOT changed:

 ** Retry push using the new branch HEAD as {{{}oldObjectId{}}}.

 # If the file-level commit has changed:

 ** Fail with proper conflict message.

This would:
 * Preserve safety (no overwrite if file actually changed).

 * Allow concurrent commits to different flow files.

 * Maintain Azure DevOps optimistic locking semantics.

 * Avoid forcing branch-per-flow model.

h3. Expected Behavior

If two different flows (different files) commit sequentially to the same branch:
 * Second commit should succeed

 * As long as its target file has not changed

 * Even if branch HEAD has moved due to other flow commits

h3. Questions for Maintainers
 # Is there a recommended pattern for monorepo usage with 
AzureDevOpsFlowRegistry?

 # Would a file-level optimistic retry mechanism be acceptable as an 
enhancement?

 # Is there an alternative supported approach to avoid branch-level 409 
conflicts in this scenario?



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to