Skip to content

Use JSON file for user preferences on Linux#2191

Draft
myieye wants to merge 1 commit intodevelopfrom
use-json-file-for-preferences-on-linux
Draft

Use JSON file for user preferences on Linux#2191
myieye wants to merge 1 commit intodevelopfrom
use-json-file-for-preferences-on-linux

Conversation

@myieye
Copy link
Collaborator

@myieye myieye commented Mar 3, 2026

Resolves #2189

@myieye myieye requested a review from rmunn March 3, 2026 16:08
@github-actions github-actions bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Mar 3, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

This PR introduces a JSON-file-backed preferences service for the FWLite backend, enabling persistent user preferences on non-MAUI platforms. It adds the JsonFilePreferencesService implementation with file I/O and thread-safety, registers it in the dependency injection container, and updates the frontend service provider to use a guaranteed service retrieval instead of optional handling.

Changes

Cohort / File(s) Summary
Backend Preferences Service
backend/FwLite/FwLiteShared/Services/JsonFilePreferencesService.cs
New service implementing IPreferencesService with JSON file persistence, in-memory caching, thread-safe operations (Get, Set, Remove), and atomic file writes with error handling.
Dependency Injection Setup
backend/FwLite/FwLiteWeb/FwLiteWebKernel.cs
Registers IPreferencesService singleton binding to JsonFilePreferencesService in the service collection.
Frontend Service Provider
frontend/viewer/src/lib/services/service-provider.ts
Renames tryUsePreferencesService() to usePreferencesService() and changes return type from IPreferencesService | undefined to IPreferencesService, enforcing guaranteed service availability.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • #2158: Adds JsonFile-backed implementation and Web DI registration of IPreferencesService in a complementary codebase.

Poem

🐰 Hops with delight

JSON files now store our wishes,
Thread-safe locks keep all our dishes,
Preferences persist through restarts anew,
No more optional, guaranteed and true! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly reflects the main change: introducing JSON file-based preferences storage for non-MAUI (Linux) platforms, which matches the core objective of the changeset.
Description check ✅ Passed The description references issue #2189 which matches the linked issues and PR objectives related to transitioning to JSON file-backed preferences for Linux.
Linked Issues check ✅ Passed The PR implements all coding requirements: JsonFilePreferencesService for backend JSON file storage [#2189], IPreferencesService registration in DI [#2189], and API changes enabling backend preference access [#2189].
Out of Scope Changes check ✅ Passed All changes are directly related to the JSON file preferences implementation objective: new service implementation, DI registration, and API refactoring to use the new preferences service.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch use-json-file-for-preferences-on-linux

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
Contributor

github-actions bot commented Mar 3, 2026

UI unit Tests

  1 files  ±0   50 suites  ±0   24s ⏱️ -1s
138 tests ±0  138 ✅ ±0  0 💤 ±0  0 ❌ ±0 
203 runs  ±0  203 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 8ba07d0. ± Comparison against base commit dc02e1c.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2026

C# Unit Tests

162 tests  ±0   162 ✅ ±0   18s ⏱️ -2s
 23 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 8ba07d0. ± Comparison against base commit dc02e1c.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@backend/FwLite/FwLiteShared/Services/JsonFilePreferencesService.cs`:
- Around line 38-55: Set and Remove currently mutate the in-memory _cache before
calling Save, so if Save throws the cache and disk diverge; modify Set(string
key, string value) and Remove(string key) to perform Save inside a try/catch and
rollback the in-memory change on failure (or persist first then update cache
atomically), ensuring the _cache remains consistent with disk. Specifically, for
Set, record the prior value/existence for key, call Save, and if Save throws
restore the previous state and log the exception; for Remove, only remove from
_cache after a successful Save or remove then catch exceptions and reinstate the
removed value, logging the error from Save; keep locking with _lock around the
whole operation to maintain thread-safety and use the existing Save and _cache
symbols.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc02e1c and 8ba07d0.

📒 Files selected for processing (3)
  • backend/FwLite/FwLiteShared/Services/JsonFilePreferencesService.cs
  • backend/FwLite/FwLiteWeb/FwLiteWebKernel.cs
  • frontend/viewer/src/lib/services/service-provider.ts

Comment on lines +38 to +55
public void Set(string key, string value)
{
lock (_lock)
{
_cache[key] = value;
Save();
}
}

[JSInvokable]
public void Remove(string key)
{
lock (_lock)
{
if (_cache.Remove(key))
{
Save();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent cache/disk divergence when Save() fails.

Set/Remove update _cache before persisting. If Line 43/54 throws, Get returns unsaved values, which is inconsistent state.

Proposed fix (rollback + error logging)
 [JSInvokable]
 public void Set(string key, string value)
 {
     lock (_lock)
     {
+        var hadOldValue = _cache.TryGetValue(key, out var oldValue);
         _cache[key] = value;
-        Save();
+        try
+        {
+            Save();
+        }
+        catch (Exception e)
+        {
+            if (hadOldValue) _cache[key] = oldValue!;
+            else _cache.Remove(key);
+            _logger.LogError(e, "Failed to save preferences to {FilePath}", _filePath);
+            throw;
+        }
     }
 }

 [JSInvokable]
 public void Remove(string key)
 {
     lock (_lock)
     {
-        if (_cache.Remove(key))
+        if (!_cache.TryGetValue(key, out var oldValue)) return;
+        _cache.Remove(key);
+        try
         {
             Save();
         }
+        catch (Exception e)
+        {
+            _cache[key] = oldValue;
+            _logger.LogError(e, "Failed to save preferences to {FilePath}", _filePath);
+            throw;
+        }
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@backend/FwLite/FwLiteShared/Services/JsonFilePreferencesService.cs` around
lines 38 - 55, Set and Remove currently mutate the in-memory _cache before
calling Save, so if Save throws the cache and disk diverge; modify Set(string
key, string value) and Remove(string key) to perform Save inside a try/catch and
rollback the in-memory change on failure (or persist first then update cache
atomically), ensuring the _cache remains consistent with disk. Specifically, for
Set, record the prior value/existence for key, call Save, and if Save throws
restore the previous state and log the exception; for Remove, only remove from
_cache after a successful Save or remove then catch exceptions and reinstate the
removed value, logging the error from Save; keep locking with _lock around the
whole operation to maintain thread-safety and use the existing Save and _cache
symbols.

@argos-ci
Copy link

argos-ci bot commented Mar 3, 2026

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

Build Status Details Updated (UTC)
default (Inspect) ⚠️ Changes detected (Review) 8 removed Mar 3, 2026, 4:26 PM

@myieye myieye marked this pull request as draft March 3, 2026 16:51
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use JSON file for user preferences on Linux

1 participant