Browse Source

Add timeout for subscription error

- Add 1 second timeout for subscription fail
- Add tests

Fixes: #159
Alexey Edelev 4 years ago
parent
commit
34baae42e5
2 changed files with 35 additions and 1 deletions
  1. 10 1
      src/grpc/qabstractgrpcclient.cpp
  2. 25 0
      tests/test_grpc/clienttest.cpp

+ 10 - 1
src/grpc/qabstractgrpcclient.cpp

@@ -153,7 +153,16 @@ QGrpcSubscriptionShared QAbstractGrpcClient::subscribe(const QString &method, co
         *errorConnection = connect(subscription.get(), &QGrpcSubscription::error, this, [this, subscription](const QGrpcStatus &status) {
         *errorConnection = connect(subscription.get(), &QGrpcSubscription::error, this, [this, subscription](const QGrpcStatus &status) {
             qProtoWarning() << subscription->method() << "call" << dPtr->service << "subscription error: " << status.message();
             qProtoWarning() << subscription->method() << "call" << dPtr->service << "subscription error: " << status.message();
             error(status);
             error(status);
-            dPtr->channel->subscribe(subscription.get(), dPtr->service, this);
+            std::weak_ptr<QGrpcSubscription> weakSubscription = subscription;
+            //TODO: Make timeout configurable from channel settings
+            QTimer::singleShot(1000, this, [this, weakSubscription, method = subscription->method()] {
+                auto subscription = weakSubscription.lock();
+                if (subscription) {
+                    dPtr->channel->subscribe(subscription.get(), dPtr->service, this);
+                } else {
+                    qProtoDebug() << "Subscription for " << dPtr->service << "method" << method << " will not be restored by timeout.";
+                }
+            });
         });
         });
 
 
         auto finishedConnection = std::make_shared<QMetaObject::Connection>();
         auto finishedConnection = std::make_shared<QMetaObject::Connection>();

+ 25 - 0
tests/test_grpc/clienttest.cpp

@@ -745,3 +745,28 @@ TEST_F(ClientTest, AttachChannelThreadTest)
                  }, ".*");
                  }, ".*");
 }
 }
 
 
+TEST_F(ClientTest, StreamCancelWhileErrorTimeoutTest)
+{
+    TestServiceClient testClient;
+    testClient.attachChannel(std::make_shared<QGrpcHttp2Channel>(QUrl("http://localhost:50052", QUrl::StrictMode), QGrpcInsecureCallCredentials() | QGrpcInsecureChannelCredentials()));//Invalid port
+    SimpleStringMessage result;
+    SimpleStringMessage request;
+    request.setTestFieldString("Stream");
+
+    QEventLoop waiter;
+
+    bool ok = false;
+    auto subscription = testClient.subscribeTestMethodServerStreamUpdates(request);
+    QObject::connect(subscription.get(), &QGrpcSubscription::finished, &m_app, [&ok, &waiter]() {
+        ok = true;
+        waiter.quit();
+    });
+    subscription->cancel();
+    subscription.reset();
+
+    QTimer::singleShot(5000, &waiter, &QEventLoop::quit);
+    waiter.exec();
+
+    ASSERT_TRUE(ok);
+}
+