mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
improve isolate lifecycle and add timeouts
- Add StreamSubscription to manage ReceivePort listener lifecycle - Introduce handshake timeout when waiting for isolate SendPort to prevent hangs - Add response timeout in get<T>() to avoid indefinitely waiting for isolate replies - Replace direct ReceivePort.listen with tracked subscription for safer cleanup - Improve error handling for invalid or missing isolate responses - Strengthen isolate startup reliability and shutdown consistency
This commit is contained in:
parent
8444e308ad
commit
09684a2641
1 changed files with 22 additions and 3 deletions
|
|
@ -21,6 +21,7 @@ class GetIsolateService {
|
|||
bool _isRunning = false;
|
||||
Isolate? _getIsolateService;
|
||||
ReceivePort? _receivePort;
|
||||
StreamSubscription? _receiveSub;
|
||||
SendPort? _sendPort;
|
||||
|
||||
Future<void> start() async {
|
||||
|
|
@ -47,7 +48,7 @@ class GetIsolateService {
|
|||
);
|
||||
|
||||
final completer = Completer<SendPort>();
|
||||
_receivePort!.listen((message) {
|
||||
_receiveSub = _receivePort!.listen((message) {
|
||||
if (message is SendPort) {
|
||||
completer.complete(message);
|
||||
}
|
||||
|
|
@ -66,7 +67,10 @@ class GetIsolateService {
|
|||
}
|
||||
});
|
||||
|
||||
_sendPort = await completer.future;
|
||||
_sendPort = await completer.future.timeout(
|
||||
const Duration(seconds: 5),
|
||||
onTimeout: () => throw StateError('Isolate handshake timed out'),
|
||||
);
|
||||
_isRunning = true;
|
||||
}
|
||||
|
||||
|
|
@ -175,8 +179,19 @@ class GetIsolateService {
|
|||
|
||||
final responsePort = ReceivePort();
|
||||
final completer = Completer<T>();
|
||||
late final StreamSubscription sub;
|
||||
|
||||
responsePort.listen((response) {
|
||||
// Timeout safeguard
|
||||
final timer = Timer(const Duration(seconds: 10), () {
|
||||
if (!completer.isCompleted) {
|
||||
sub.cancel();
|
||||
responsePort.close();
|
||||
completer.completeError('Isolate response timeout');
|
||||
}
|
||||
});
|
||||
sub = responsePort.listen((response) {
|
||||
timer.cancel();
|
||||
sub.cancel();
|
||||
responsePort.close();
|
||||
if (response is Map<String, dynamic>) {
|
||||
if (response['success'] == true) {
|
||||
|
|
@ -184,6 +199,8 @@ class GetIsolateService {
|
|||
} else {
|
||||
completer.completeError(response['error']);
|
||||
}
|
||||
} else {
|
||||
completer.completeError('Invalid isolate response: $response');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -210,7 +227,9 @@ class GetIsolateService {
|
|||
|
||||
_sendPort?.send('dispose');
|
||||
_getIsolateService?.kill(priority: Isolate.immediate);
|
||||
await _receiveSub?.cancel();
|
||||
_receivePort?.close();
|
||||
_receiveSub = null;
|
||||
_sendPort = null;
|
||||
_getIsolateService = null;
|
||||
_receivePort = null;
|
||||
|
|
|
|||
Loading…
Reference in a new issue