From b999b64502508177811e7316580230b8afef780d Mon Sep 17 00:00:00 2001 From: Galen Warren Date: Wed, 17 Jul 2024 08:11:29 -0400 Subject: [PATCH] feat: fix hang that occurs when hot restarting (#718) --- CHANGELOG.md | 1 + lib/src/client/transport/web_streams.dart | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d336d3de..398f2c81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Remove generated status codes. * Remove dependency on `package:archive`. * Move `codec.dart`. +* Work around hang during Flutter hot restart by adding default case handler in _GrpcWebConversionSink.add. ## 3.2.4 diff --git a/lib/src/client/transport/web_streams.dart b/lib/src/client/transport/web_streams.dart index aba0a7bc..8480ab29 100644 --- a/lib/src/client/transport/web_streams.dart +++ b/lib/src/client/transport/web_streams.dart @@ -132,6 +132,16 @@ class _GrpcWebConversionSink implements ChunkedConversionSink { void add(ByteBuffer chunk) { _chunkOffset = 0; final chunkData = chunk.asUint8List(); + // in flutter web, when a hot-restart is requested, the code can get stuck + // in the following loop if there is an active streaming call. the + // switch statement is invoked but doesn't match any of the cases. this + // presumably has something to do how enums work across isolates. + // possibly related to https://github.com/dart-lang/sdk/issues/35626. + // + // in any case, adding a default handler to the switch statement + // causes this loop to end in that case, allowing the old isolate + // to shut down and the hot-restart to work properly. + processingLoop: while (_chunkOffset < chunk.lengthInBytes) { switch (_state) { case _GrpcWebParseState.init: @@ -143,6 +153,9 @@ class _GrpcWebConversionSink implements ChunkedConversionSink { case _GrpcWebParseState.message: _parseMessage(chunkData); break; + default: + // only expected to be hit when hot-restarting, see above + break processingLoop; } } _chunkOffset = 0;