Skip to content

Conversation

@myieye
Copy link
Collaborator

@myieye myieye commented Oct 22, 2025

This addresses the critical danger of #2052.

EDIT: Actually, this fix would result in all the CRDT changes being overridden if an exception was thrown without a roll-back happening... 😬 (e.g. this exception).
EDIT2:....actually that's not true. It would just result in repeating the same sync, which already happens if an exception is thrown anywhere else in the sync pipeline. It's suboptimal and a bit noisy, but is not expected to lose data, so mostly harmless.

EDIT3: After chatting with Jason, it sounds like roll-backs should be considered an extreme case. Based on that, I might try to implement my initial proposal/plan, but only if the exception explicitly results in a rollback. I'm assuming we can fairly safely determine that.

We're not in a position where we could easily write a test for this change.

Planned work for this PR:

  • Using mocks call SyncWorker.ExecuteSync
    • verify the order of steps in a success case
    • verify the order and omission/inclusion of steps in various failure cases
  • Explicitly pass the project snapshot to CrdtFwdataProjectSyncService.Sync()
    • That will mean a bit more manual work when calling Sync() in tests, but I think overall it will be cleaner. Currently in some tests we BypassImport() by creating a snapshot in the background. That will become more declarative when we pass the snapshot explicitly.

@github-actions github-actions bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Oct 22, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

📝 Walkthrough

Walkthrough

The changes reorganize project snapshot regeneration logic during CRDT-FW synchronization. Automatic snapshot regeneration is removed from the main sync service, made conditionally applied in the hosted service based on CRDT changes, and explicitly invoked in test operations.

Changes

Cohort / File(s) Summary
Hosted Service Logic
backend/FwHeadless/Services/SyncHostedService.cs
Removed unconditional early call to crdtSyncService.SyncHarmonyProject(). Introduced conditional block to regenerate project snapshot when result.CrdtChanges > 0 with associated logging; added else branch to log when skipping regeneration. Moved SyncHarmonyProject() call to occur after snapshot handling.
Core Sync Service
backend/FwLite/FwLiteProjectSync/CrdtFwdataProjectSyncService.cs
Removed post-sync project snapshot regeneration logic. The block that called RegenerateProjectSnapshot() after non-dry-run sync operations has been deleted.
Test Suites
backend/FwLite/FwLiteProjectSync.Tests/CrdtRepairTests.cs, backend/FwLite/FwLiteProjectSync.Tests/Sena3SyncTests.cs
Added explicit calls to RegenerateProjectSnapshot() after sync operations in two repair tests and one Sena3 sync test to ensure snapshots align with sync-applied changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

The diff introduces conditional snapshot regeneration logic in the hosted service, removes automatic regeneration from the sync service, and adds explicit snapshot calls in tests. This requires understanding the sync workflow timing and snapshot lifecycle implications across multiple layers.

Possibly related PRs

Suggested reviewers

  • hahn-kev

Poem

🐰 Snapshots once flowed automatic and free,
Now conditional wisdom guides what shall be,
With CRDT changes, we'll generate anew,
Moved and arranged for a cleaner, truer view!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "Only regenerate snapshot if Send/Receive works" is clearly related to the main changes in the changeset. The modifications restructure snapshot regeneration to be conditional rather than automatic: removing automatic regeneration from CrdtFwdataProjectSyncService, adding conditional regeneration in SyncHostedService based on result.CrdtChanges, and adding explicit regeneration calls in test files. The title accurately captures this primary change—moving from unconditional to conditional snapshot regeneration tied to synchronization success. The phrasing is concise and specific enough that a teammate scanning the history would understand the core intent.
Description check ✅ Passed The pull request description clearly relates to the changeset, addressing issue #2052 and explaining the motivation for moving snapshot regeneration logic to occur conditionally after successful sync operations.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2052-only-regenerate-snapshot-if-send-receive-works

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

C# Unit Tests

0 tests   - 130   0 ✅  - 130   0s ⏱️ -18s
0 suites  -  20   0 💤 ±  0 
0 files    -   1   0 ❌ ±  0 

Results for commit 1437481. ± Comparison against base commit 19cc689.

@argos-ci
Copy link

argos-ci bot commented Oct 22, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Oct 22, 2025, 3:24 PM

@github-actions
Copy link

UI unit Tests

  1 files  ±0   45 suites  ±0   29s ⏱️ -1s
111 tests ±0  111 ✅ ±0  0 💤 ±0  0 ❌ ±0 
160 runs  ±0  160 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 1437481. ± Comparison against base commit 19cc689.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19cc689 and 1437481.

📒 Files selected for processing (4)
  • backend/FwHeadless/Services/SyncHostedService.cs (1 hunks)
  • backend/FwLite/FwLiteProjectSync.Tests/CrdtRepairTests.cs (2 hunks)
  • backend/FwLite/FwLiteProjectSync.Tests/Sena3SyncTests.cs (1 hunks)
  • backend/FwLite/FwLiteProjectSync/CrdtFwdataProjectSyncService.cs (0 hunks)
💤 Files with no reviewable changes (1)
  • backend/FwLite/FwLiteProjectSync/CrdtFwdataProjectSyncService.cs
🧰 Additional context used
🧬 Code graph analysis (2)
backend/FwHeadless/Services/SyncHostedService.cs (1)
backend/LexCore/Entities/Project.cs (1)
  • Project (9-75)
backend/FwLite/FwLiteProjectSync.Tests/CrdtRepairTests.cs (1)
backend/FwLite/FwLiteShared/Sync/SyncService.cs (1)
  • SyncService (23-240)
🪛 GitHub Actions: Develop FwHeadless CI/CD
backend/FwHeadless/Services/SyncHostedService.cs

[error] 223-223: CS1002: ; expected. Command: dotnet build backend/FwHeadless/FwHeadless.csproj

🪛 GitHub Check: Build FwHeadless / publish-fw-headless
backend/FwHeadless/Services/SyncHostedService.cs

[failure] 223-223:
} expected


[failure] 223-223:
; expected


[failure] 223-223:
} expected


[failure] 223-223:
; expected

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Build API / publish-api
  • GitHub Check: Build FW Lite and run tests
  • GitHub Check: frontend
  • GitHub Check: frontend-component-unit-tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (5)
backend/FwLite/FwLiteProjectSync.Tests/Sena3SyncTests.cs (1)

228-228: Test adapted to new explicit snapshot regeneration pattern.

The explicit call to RegenerateProjectSnapshot after Sync is the expected pattern following the removal of automatic snapshot regeneration from the sync service.

backend/FwLite/FwLiteProjectSync.Tests/CrdtRepairTests.cs (2)

93-93: Test adapted to new explicit snapshot regeneration pattern.

The explicit call to RegenerateProjectSnapshot after Sync is the expected pattern following the removal of automatic snapshot regeneration from the sync service.


160-160: Test adapted to new explicit snapshot regeneration pattern.

The explicit call to RegenerateProjectSnapshot after Sync is the expected pattern following the removal of automatic snapshot regeneration from the sync service.

backend/FwHeadless/Services/SyncHostedService.cs (2)

210-224: Conditional snapshot regeneration correctly implements PR objective.

The logic correctly ensures snapshots are only regenerated when:

  1. CRDT changes exist (result.CrdtChanges > 0), AND
  2. Send/Receive either succeeded or wasn't needed (no early return at line 203)

If Send/Receive fails after CRDT sync (line 203), the early return prevents snapshot regeneration, which is correct since the changes might have been rolled back.


226-226: Verify dual Harmony sync pattern is intentional.

The code now performs Harmony sync twice:

  1. Conditionally at line 176 (if HasSyncedSuccessfully)
  2. Unconditionally at line 226 (after snapshot regeneration)

This appears intentional to ensure Harmony is synced both before and after the CRDT/FW sync operations, but you may want to verify this pattern is necessary and doesn't cause redundant work.

}
else
{
logger.LogInformation("Skipping regenerating project snapshot, because there were no crdt changes"):
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix syntax error: replace colon with semicolon.

The line has a colon : instead of semicolon ; at the end, causing a compilation failure.

Apply this diff:

-            logger.LogInformation("Skipping regenerating project snapshot, because there were no crdt changes"):
+            logger.LogInformation("Skipping regenerating project snapshot, because there were no crdt changes");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
logger.LogInformation("Skipping regenerating project snapshot, because there were no crdt changes"):
logger.LogInformation("Skipping regenerating project snapshot, because there were no crdt changes");
🧰 Tools
🪛 GitHub Actions: Develop FwHeadless CI/CD

[error] 223-223: CS1002: ; expected. Command: dotnet build backend/FwHeadless/FwHeadless.csproj

🪛 GitHub Check: Build FwHeadless / publish-fw-headless

[failure] 223-223:
} expected


[failure] 223-223:
; expected


[failure] 223-223:
} expected


[failure] 223-223:
; expected

🤖 Prompt for AI Agents
In backend/FwHeadless/Services/SyncHostedService.cs around line 223, the
statement ends with a colon instead of a semicolon causing a compile error;
replace the trailing ':' with ';' so the logger.LogInformation(...) statement
terminates correctly.

@myieye myieye marked this pull request as draft October 24, 2025 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants