Conversation
📝 WalkthroughWalkthroughThis 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
backend/FwLite/FwLiteShared/Services/JsonFilePreferencesService.csbackend/FwLite/FwLiteWeb/FwLiteWebKernel.csfrontend/viewer/src/lib/services/service-provider.ts
| 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(); | ||
| } |
There was a problem hiding this comment.
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.
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
Resolves #2189