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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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