Skip to content

[Metronome] Task.sleep based follower timeout has unreliable wake precision #29

Description

@hakaru

問題

`MetronomeViewModel.scheduleFollowerTimeout` が `Task.sleep(nanoseconds:)` でタイムアウトを実装しているが、wake 精度が scheduler 依存で数十 ms の overshoot がありうる。

現状

```swift
followerTimeoutTask = Task { [weak self] in
let timeoutNs = max(intervalNs * 3 / 2, 400_000_000)
try? await Task.sleep(nanoseconds: timeoutNs)
...
await self?.followerTimedOut()
}
```

改善方針

Task.sleep は「状態遷移のきっかけ」にとどめる。実際の次クリックは wake 時点の現在時刻を基準に未来ビートを再計算して schedule する:

```swift
private func followerTimedOut() async {
...
// Don't rely on "lastBeatHostTime + 1 beat" — may be past
let now = mach_absolute_time()
let beatInterval = subIntervalMach * UInt64(subsPerBeat)
var nextBeat = lastExternalHostTime + beatInterval
while nextBeat < now { nextBeat += beatInterval; beatIndex += 1 }
...
}
```

重要度

Medium(#26 と併せて対応)

関連 issue

#26

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions