-
-
Notifications
You must be signed in to change notification settings - Fork 269
Keep last events on refresh errors #886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -174,21 +174,18 @@ public class EventManager: ObservableObject { | |
| return Deferred { | ||
| Future<([MBCalendar], [MBEvent]), Error> { promise in | ||
| Task { | ||
| let current = await MainActor.run { (self.calendars, self.events) } | ||
| do { | ||
| let cals = try await self.provider.fetchAllCalendars() | ||
| let evts = try await self.fetchEvents(fromCalendars: cals) | ||
| promise(.success((cals, evts))) | ||
| } catch { | ||
| NSLog("EventManager refresh failed: \(error)") | ||
| promise(.success(([], []))) | ||
| promise(.success(current)) | ||
|
Comment on lines
+177
to
+184
|
||
| } | ||
|
Comment on lines
176
to
185
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid stale fallback on overlapping refreshes. Capturing ✅ Suggested fix- Task {
- let current = await MainActor.run { (self.calendars, self.events) }
- do {
+ Task {
+ do {
let cals = try await self.provider.fetchAllCalendars()
let evts = try await self.fetchEvents(fromCalendars: cals)
promise(.success((cals, evts)))
} catch {
NSLog("EventManager refresh failed: \(error)")
+ let current = await MainActor.run { (self.calendars, self.events) }
promise(.success(current))
}
}🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| } | ||
| .catch { error -> Empty<([MBCalendar], [MBEvent]), Never> in | ||
| NSLog("EventManager refresh failed: \(error)") | ||
| return Empty(completeImmediately: true) | ||
| } | ||
| .eraseToAnyPublisher() | ||
| } | ||
| // **important: hop back to the main run-loop before assigning** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a potential race condition where the captured
currentstate may become stale before being used. Thecurrenttuple is captured at the start of the Task, but if a concurrent refresh successfully completes and updatesself.calendarsandself.eventson the main actor before this refresh fails, the error handler will overwrite the newer values with the oldercurrentsnapshot.This can occur when multiple refresh triggers fire in quick succession (e.g., manual refresh + timer trigger + defaults change). The second refresh could succeed and update the published properties, but then the first refresh's failure handler would revert them to the older state.
Consider either:
.sinkupdate when the values matchcurrent), orThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot open a new pull request to apply changes based on this feedback