diff --git a/src/grpc/qgrpchttp2channel.cpp b/src/grpc/qgrpchttp2channel.cpp index 6967b001..3a3a80f4 100644 --- a/src/grpc/qgrpchttp2channel.cpp +++ b/src/grpc/qgrpchttp2channel.cpp @@ -286,6 +286,7 @@ public: void finish(const QGrpcStatus &status); void asyncFinish(const QGrpcStatus &status); + void cancelWithStatus(const QGrpcStatus &status); [[nodiscard]] bool expired() const { return !m_operation; } @@ -299,10 +300,13 @@ public: } // context slot handlers: - void cancel(); + void cancel() { cancelWithStatus({ StatusCode::Cancelled, tr("Cancelled by client") }); } void writesDone(); void writeMessage(QByteArrayView data); - void deadlineTimeout(); + void deadlineTimeout() + { + cancelWithStatus({ StatusCode::DeadlineExceeded, tr("Deadline exceeded") }); + } void handleHeaders(const HPack::HttpHeader &headers, HeaderPhase phase); @@ -437,10 +441,8 @@ Http2Handler::Http2Handler(QGrpcOperationContext *operation, QGrpcHttp2ChannelPr // QHttp2Stream will handle any outstanding cancellations appropriately. QObject::connect(operation, &QGrpcOperationContext::destroyed, this, &Http2Handler::deleteLater); - QObject::connect(operation, &QGrpcOperationContext::cancelRequested, this, [this] { - cancel(); - deleteLater(); - }); + QObject::connect(operation, &QGrpcOperationContext::cancelRequested, this, + &Http2Handler::cancel); QObject::connect(operation, &QGrpcOperationContext::writesDoneRequested, this, &Http2Handler::writesDone); if (!m_endStreamAtFirstData) { @@ -704,7 +706,7 @@ void Http2Handler::asyncFinish(const QGrpcStatus &status) QTimer::singleShot(0, m_operation.get(), [this, status]() { finish(status); }); } -void Http2Handler::cancel() +void Http2Handler::cancelWithStatus(const QGrpcStatus &status) { if (m_state >= State::Cancelled) return; @@ -718,6 +720,8 @@ void Http2Handler::cancel() qGrpcDebug("Failed cancellation on stream: %p, Handler::state: %s", m_stream.get(), QDebug::toBytes(m_state).data()); } + + finish(status); } void Http2Handler::writesDone() @@ -734,14 +738,6 @@ void Http2Handler::writesDone() processQueue(); } -void Http2Handler::deadlineTimeout() -{ - Q_ASSERT_X(m_stream, "onDeadlineTimeout", "stream is not available"); - - cancel(); - finish({ StatusCode::DeadlineExceeded, "Deadline Exceeded" }); -} - void Http2Handler::handleHeaders(const HPack::HttpHeader &headers, HeaderPhase phase) { // ABNF syntax: Rule, [Optional-Rule], *Variable-Repetition diff --git a/src/grpc/qgrpcoperation.cpp b/src/grpc/qgrpcoperation.cpp index 7d3a1d13..922c36f4 100644 --- a/src/grpc/qgrpcoperation.cpp +++ b/src/grpc/qgrpcoperation.cpp @@ -149,13 +149,10 @@ bool QGrpcOperation::read(QProtobufMessage *message) const */ void QGrpcOperation::cancel() { - if (!isFinished()) { - Q_D(QGrpcOperation); - d->isFinished.storeRelaxed(true); - emit d->operationContext->cancelRequested(); - Q_EMIT finished(QGrpcStatus{ QtGrpc::StatusCode::Cancelled, - tr("Operation is cancelled by client") }); - } + if (isFinished()) + return; + Q_D(QGrpcOperation); + emit d->operationContext->cancelRequested(); } /*! diff --git a/src/grpc/qgrpcoperationcontext.cpp b/src/grpc/qgrpcoperationcontext.cpp index b31906f8..db1ac2d9 100644 --- a/src/grpc/qgrpcoperationcontext.cpp +++ b/src/grpc/qgrpcoperationcontext.cpp @@ -103,8 +103,9 @@ QT_BEGIN_NAMESPACE This signal is emitted by QGrpcOperation when requesting cancellation of the communication. - The channel is expected to connect its cancellation logic to this signal and - attempt to cancel the RPC and return immediately. Successful cancellation + The channel is expected to connect its cancellation logic to this signal + and attempt to cancel the RPC and finish it with a + \l{QtGrpc::StatusCode::}{Cancelled} status code. Successful cancellation cannot be guaranteed. Further processing of the data received from a channel is not required and should be avoided. diff --git a/tests/auto/grpc/client/deadline/tst_grpc_client_deadline.cpp b/tests/auto/grpc/client/deadline/tst_grpc_client_deadline.cpp index cf9a67ed..7288de81 100644 --- a/tests/auto/grpc/client/deadline/tst_grpc_client_deadline.cpp +++ b/tests/auto/grpc/client/deadline/tst_grpc_client_deadline.cpp @@ -49,7 +49,7 @@ void QtGrpcClientDeadlineTest::channelDeadlineCallExceeds() const auto code = qvariant_cast(finSpy.at(0).first()); QCOMPARE_EQ(code.code(), QtGrpc::StatusCode::DeadlineExceeded); - QCOMPARE_EQ(code.message(), QString("Deadline Exceeded")); + QVERIFY(!code.message().isEmpty()); } void QtGrpcClientDeadlineTest::channelDeadlineCallFinishes()