Initial commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import 'dart:async';
|
||||
|
||||
|
||||
class RelinkScheduler {
|
||||
RelinkScheduler({
|
||||
this.maxAttempts = 3,
|
||||
this.backoffs = const [
|
||||
Duration.zero,
|
||||
Duration(seconds: 2),
|
||||
Duration(seconds: 5),
|
||||
],
|
||||
}) : assert(maxAttempts > 0),
|
||||
assert(backoffs.isNotEmpty);
|
||||
|
||||
final int maxAttempts;
|
||||
final List<Duration> backoffs;
|
||||
|
||||
int _attempts = 0;
|
||||
bool _pending = false;
|
||||
Timer? _backoffTimer;
|
||||
Timer? _sustainTimer;
|
||||
|
||||
|
||||
bool get pending => _pending;
|
||||
|
||||
|
||||
int get attempts => _attempts;
|
||||
|
||||
|
||||
bool schedule({
|
||||
required void Function(Duration delay) onRelink,
|
||||
required void Function() onGiveUp,
|
||||
}) {
|
||||
if (_pending) return false;
|
||||
|
||||
|
||||
_sustainTimer?.cancel();
|
||||
|
||||
if (_attempts >= maxAttempts) {
|
||||
onGiveUp();
|
||||
return false;
|
||||
}
|
||||
final backoffIndex = _attempts.clamp(0, backoffs.length - 1);
|
||||
final delay = backoffs[backoffIndex];
|
||||
_attempts++;
|
||||
|
||||
_pending = true;
|
||||
_backoffTimer?.cancel();
|
||||
_backoffTimer = Timer(delay, () {
|
||||
_pending = false;
|
||||
onRelink(delay);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void armSustain({Duration sustain = const Duration(seconds: 30)}) {
|
||||
_sustainTimer?.cancel();
|
||||
_sustainTimer = Timer(sustain, () => _attempts = 0);
|
||||
}
|
||||
|
||||
|
||||
void cancelPending() {
|
||||
_backoffTimer?.cancel();
|
||||
_pending = false;
|
||||
}
|
||||
|
||||
|
||||
void reset() => _attempts = 0;
|
||||
|
||||
|
||||
void dispose() {
|
||||
_backoffTimer?.cancel();
|
||||
_sustainTimer?.cancel();
|
||||
_pending = false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user