Bound the relay connect handshake so a fetch can't hang forever
This commit is contained in:
parent
0e70aba755
commit
60f9e4ccfa
3 changed files with 41 additions and 1 deletions
|
|
@ -9,11 +9,15 @@ final class FakeRelayConnection implements RelayConnection {
|
|||
bool isConnected = false;
|
||||
bool autoRespond = true;
|
||||
bool throwOnConnect = false;
|
||||
// When set, connect() never completes — simulates a handshake that hangs
|
||||
// (accepted socket, no WebSocket upgrade).
|
||||
bool hangOnConnect = false;
|
||||
void Function(String subId)? onReq;
|
||||
|
||||
@override
|
||||
Future<void> connect() async {
|
||||
if (throwOnConnect) throw Exception('connection failed');
|
||||
if (hangOnConnect) await Completer<void>().future;
|
||||
isConnected = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,6 +120,34 @@ void main() {
|
|||
expect((result as EventsFetched).events, hasLength(1));
|
||||
});
|
||||
|
||||
test('bounds a hung connect so the fetch cannot stall forever', () async {
|
||||
final fakeHang = FakeRelayConnection()..hangOnConnect = true;
|
||||
final fakeUp = FakeRelayConnection();
|
||||
addTearDown(fakeHang.dispose);
|
||||
addTearDown(fakeUp.dispose);
|
||||
|
||||
final event = _makeEvent('id1');
|
||||
fakeUp.onReq = (subId) {
|
||||
fakeUp.push(jsonEncode(['EVENT', subId, event]));
|
||||
fakeUp.push(jsonEncode(['EOSE', subId]));
|
||||
};
|
||||
|
||||
final fakes = {'ws://hang': fakeHang, 'ws://up': fakeUp};
|
||||
final actor = NostrFetchActor(
|
||||
relayUrls: ['ws://hang', 'ws://up'],
|
||||
connectDeadline: const Duration(milliseconds: 50),
|
||||
connectionFactory: (url) => fakes[url]!,
|
||||
);
|
||||
|
||||
// The outer timeout is a guard: without the connect deadline this hangs.
|
||||
final result = await actor
|
||||
.handle(const FetchEvents(_filter))
|
||||
.timeout(const Duration(seconds: 2));
|
||||
|
||||
expect(result, isA<EventsFetched>());
|
||||
expect((result as EventsFetched).events, hasLength(1));
|
||||
});
|
||||
|
||||
test('sends CLOSE after EOSE', () async {
|
||||
final fake = FakeRelayConnection();
|
||||
addTearDown(fake.dispose);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue