Skip to content

Commit aaf981b

Browse files
committed
Restructures SocketConnectionAttempt
1 parent 6c27b0e commit aaf981b

File tree

1 file changed

+71
-16
lines changed

1 file changed

+71
-16
lines changed

lib/src/socket_connection_attempt.dart

+71-16
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,56 @@ import 'dart:math';
33

44
final _random = Random();
55

6-
final class SocketConnectionAttempt {
7-
SocketConnectionAttempt({required Duration delay}) {
6+
sealed class SocketConnectionAttempt {
7+
SocketConnectionAttempt._();
8+
9+
// Created a socket connection attempt whose delayFuture will complete after
10+
// the given delay.
11+
factory SocketConnectionAttempt({required Duration delay}) =>
12+
_DelayedSocketConnectionAttempt(delay: delay);
13+
14+
// Creates a socket connection attempt whose delayFuture is completed with an
15+
// error.
16+
factory SocketConnectionAttempt.aborted() =>
17+
_AbortedSocketConnectionAttempt();
18+
19+
final int _id = _random.nextInt(1 << 32);
20+
late final idAsString = _id.toRadixString(16).padLeft(8, '0');
21+
22+
/// Whether the delayFuture has completed with either succesfully or with an
23+
/// error.
24+
bool get delayDone;
25+
26+
// Future that completes successfully when the delay connection attempt should
27+
// be performed.
28+
Future<void> get delayFuture;
29+
30+
// Immediately successfully completes [delayFuture]. Has no effect if the
31+
// future was already completed.
32+
void skipDelay();
33+
34+
// Immediately completes [delayFuture] with an error. Has no effect if the
35+
// future was already completed.
36+
void abort();
37+
}
38+
39+
final class _DelayedSocketConnectionAttempt extends SocketConnectionAttempt {
40+
_DelayedSocketConnectionAttempt({required Duration delay}) : super._() {
841
_delayTimer = Timer(delay, () {
942
if (!_delayCompleter.isCompleted) {
1043
_delayCompleter.complete();
1144
}
1245
});
1346
}
1447

15-
SocketConnectionAttempt.aborted() {
16-
_delayTimer = Timer(Duration.zero, () {});
17-
delayFuture.ignore();
18-
abort();
19-
}
20-
21-
final int _id = _random.nextInt(1 << 32);
22-
late final idAsString = _id.toRadixString(16).padLeft(8, '0');
23-
48+
late Timer _delayTimer;
2449
final Completer<void> _delayCompleter = Completer();
25-
bool get delayDone => _delayCompleter.isCompleted;
50+
@override
2651
late final Future<void> delayFuture = _delayCompleter.future;
52+
@override
53+
bool get delayDone => _delayCompleter.isCompleted;
2754

28-
late Timer _delayTimer;
29-
55+
@override
3056
void skipDelay() {
3157
if (_delayTimer.isActive) {
3258
_delayTimer.cancel();
@@ -36,6 +62,7 @@ final class SocketConnectionAttempt {
3662
}
3763
}
3864

65+
@override
3966
void abort() {
4067
if (_delayTimer.isActive) {
4168
_delayTimer.cancel();
@@ -50,14 +77,42 @@ final class SocketConnectionAttempt {
5077

5178
@override
5279
bool operator ==(Object other) {
53-
return other is SocketConnectionAttempt && _id == other._id;
80+
return other is _DelayedSocketConnectionAttempt && _id == other._id;
5481
}
5582

5683
@override
5784
int get hashCode => _id.hashCode;
5885

5986
@override
6087
String toString() {
61-
return 'SocketConnectionAttempt(id: $idAsString)';
88+
return 'DelayedSocketConnectionAttempt(id: $idAsString)';
6289
}
6390
}
91+
92+
final class _AbortedSocketConnectionAttempt extends SocketConnectionAttempt {
93+
_AbortedSocketConnectionAttempt() : super._();
94+
95+
@override
96+
bool delayDone = false;
97+
98+
@override
99+
late final Future<void> delayFuture =
100+
// Future.error completes after a microtask, so to be perfectly ok with
101+
// the superclass API, we set delayDone to true after the microtask is
102+
// done.
103+
Future.error('Attempt aborted').whenComplete(() => delayDone = true);
104+
105+
@override
106+
void abort() {}
107+
108+
@override
109+
void skipDelay() {}
110+
111+
@override
112+
bool operator ==(Object other) {
113+
return other is _AbortedSocketConnectionAttempt && other._id == _id;
114+
}
115+
116+
@override
117+
int get hashCode => _id.hashCode;
118+
}

0 commit comments

Comments
 (0)