grpc / grpc-dart

The Dart language implementation of gRPC.
https://pub.dev/packages/grpc
Apache License 2.0
835 stars 256 forks source link

Is ResponseStream.cancel supposed to update ServiceCall.isCancelled? #687

Closed crasm closed 5 months ago

crasm commented 5 months ago

I have a dart gRPC server that has a function that generates a stream.

In my Flutter app client, I call ResponseStream.cancel. However, this cancellation never gets logged on the server, even though I'm checking consistently.

Is this expected behavior? Am I supposed to send a cancellation message myself, via e.g. a message through bidirectional streaming? The documentation sounds as if the ServiceCall.isCanceled should be updated when the remote client cancels.

If this is a bug, then it may be the cause of #681, since I was getting that same error. Starting another RPC while a long-running stream RPC is continuing (unbeknownst to the client, which thinks it was canceled) causes the HTTP2 error.

Any advice and/or help much appreciated. (On the latest,grpc 3.2.4)

  @override
  Stream<proto.Token> generate(grpc.ServiceCall call, proto.Context context) async* {
    try {
      final tokStream = _ctx.generate(samplers: [
        RepetitionPenalty(),
        MinP(0.18),
        Temperature(1.0),
      ]).map((tok) => proto.Token(id: tok.id, textUtf8: utf8.encode(tok.text)));

      await for (final tok in tokStream) {
        if (call.isCanceled) {
          _log.info('Client canceled generation');
          return;
        } else {
          yield tok;
        }
      }
    } catch (e) {
      _log.severe(e);
    }
  }
}
crasm commented 5 months ago

Not a gRPC issue. In this case, needed to add an await Future.delayed(const Duration()); after yield tok; to give gRPC a chance to process the client cancellation.