From 564ea71f99d76dcfe328948d1860e1b64104c0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=AA=E3=81=A4=E3=81=8D?= Date: Fri, 16 Aug 2024 23:04:01 -0700 Subject: [PATCH] Fix flaky isolate shutdown --- lib/src/embedded/compilation_dispatcher.dart | 32 +++++++------------- lib/src/embedded/reusable_isolate.dart | 5 ++- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/lib/src/embedded/compilation_dispatcher.dart b/lib/src/embedded/compilation_dispatcher.dart index 8f69b2553..d6f19219c 100644 --- a/lib/src/embedded/compilation_dispatcher.dart +++ b/lib/src/embedded/compilation_dispatcher.dart @@ -51,24 +51,18 @@ final class CompilationDispatcher { /// This is used in outgoing messages. late Uint8List _compilationIdVarint; - /// Whether we detected a [ProtocolError] while parsing an incoming response. - /// - /// If we have, we don't want to send the final compilation result because - /// it'll just be a wrapper around the error. - var _requestError = false; - /// Creates a [CompilationDispatcher] that receives encoded protocol buffers /// through [_mailbox] and sends them through [_sendPort]. CompilationDispatcher(this._mailbox, this._sendPort); /// Listens for incoming `CompileRequests` and runs their compilations. void listen() { - do { + while (true) { Uint8List packet; try { packet = _mailbox.take(); } on StateError catch (_) { - break; + Isolate.exit(); } try { @@ -88,9 +82,7 @@ final class CompilationDispatcher { case InboundMessage_Message.compileRequest: var request = message.compileRequest; var response = _compile(request); - if (!_requestError) { - _send(OutboundMessage()..compileResponse = response); - } + _send(OutboundMessage()..compileResponse = response); case InboundMessage_Message.versionRequest: throw paramsError("VersionRequest must have compilation ID 0."); @@ -112,8 +104,10 @@ final class CompilationDispatcher { } } catch (error, stackTrace) { _handleError(error, stackTrace); + _mailbox.close(); + Isolate.exit(); } - } while (!_requestError); + } } OutboundMessage_CompileResponse _compile( @@ -290,11 +284,10 @@ final class CompilationDispatcher { /// Sends [error] to the host. /// /// This is used during compilation by other classes like host callable. - /// Therefore it must set _requestError = true to prevent sending a CompileFailure after - /// sending a ProtocolError. void sendError(ProtocolError error) { _sendError(error); - _requestError = true; + _mailbox.close(); + Isolate.exit(); } /// Sends [error] to the host. @@ -330,10 +323,7 @@ final class CompilationDispatcher { try { packet = _mailbox.take(); } on StateError catch (_) { - // Compiler is shutting down, throw without calling `_handleError` as we - // don't want to report this as an actual error. - _requestError = true; - rethrow; + Isolate.exit(); } try { @@ -376,8 +366,8 @@ final class CompilationDispatcher { return response; } catch (error, stackTrace) { _handleError(error, stackTrace); - _requestError = true; - rethrow; + _mailbox.close(); + Isolate.exit(); } } diff --git a/lib/src/embedded/reusable_isolate.dart b/lib/src/embedded/reusable_isolate.dart index 5cdd6bbd8..ddb9c7ddd 100644 --- a/lib/src/embedded/reusable_isolate.dart +++ b/lib/src/embedded/reusable_isolate.dart @@ -118,12 +118,11 @@ class ReusableIsolate { /// Shuts down the isolate. void kill() { - _isolate.kill(); - _receivePort.close(); - // If the isolate is blocking on [Mailbox.take], it won't even process a // kill event, so we closed the mailbox to nofity and wake it up. _mailbox.close(); + _receivePort.close(); + _isolate.kill(priority: Isolate.immediate); } }