0

我从这里使用 google-cloud-cpp SDK ,我正在尝试测试一个不正确的端点场景,根据我在传入不正确的端点 url 时设置的策略,我期望在 100 毫秒内出现错误。但是,我的测试却挂了很长时间。对于这种特殊情况,我只需要为 ListObjects 案例覆盖现有 gcs::Client 的策略,并希望重新使用我已经创建的客户端。我写了一个小程序来模拟我在代码库中的实际问题的行为。我不确定为什么LimitedTimeRetryPolicy的重试策略没有转发到我创建的新客户端?感谢任何帮助和/或示例。

using namespace google::cloud::storage;
using ::google::cloud::StatusOr;
// Ex: ./wrongEndpoint
int main(int argc, char* argv[]) {
    auto options = ClientOptions::CreateDefaultClientOptions();
    options.value().set_enable_http_tracing(true);
    options.value().set_enable_raw_client_tracing(true);
    options.value().set_endpoint("https://somegarbage.com");
    options.value().set_download_stall_timeout(std::chrono::seconds(1));

    // Original Client in the codebase
    Client clientX(*options);

    // Creating new client for ListObjects from the raw_client with a retry policy
    std::shared_ptr<internal::RawClient> Rclient = clientX.raw_client();
    Client client = Client(Rclient, LimitedTimeRetryPolicy(std::chrono::milliseconds(100)));
    try{
        for (auto&& object_metadata : client.ListObjects("march30")) {
            if (!object_metadata) {
                throw std::runtime_error(object_metadata.status().message());
            }

            std::cout << "bucket_name=" << object_metadata->bucket()
                << ", object_name=" << object_metadata->name() << "\n";
        }
    } catch(std::exception &ex) {
        std::cout << ex.what() << "\n";
    }
}
4

1 回答 1

0

要理解为什么这不起作用,我需要谈谈实现内部,抱歉。

在您的代码clientX中包含一堆RawClient对象,或多或少如下:clientX-> LoggingClient-> RetryClient(DefaultRetryPolicy)-> CurlClient。该列表中的每个元素都是一个装饰器,它执行一个功能(例如日志记录)并将工作委托给下一个元素。

当您client在代码中创建时,它包含一个新堆栈client-> RetryClient(LimitedTimeRetryPolicy(100ms))-> LoggingClient-> RetryClient(DefaultRetryPolicy)-> CurlClient

这意味着每个请求现在都受原始重试策略您的新重试策略的约束,新的重试策略比原始重试策略短得多,因此(很可能)它会立即失败。

重建internal::RawClient对象堆栈不是我们曾经想过的事情。我可以描述如何做到这一点,但我会注意到您将使用google::cloud::internal::命名空间中的类,这些类可能随时更改,恕不另行通知。

基本上,您需要使用 RTTI 来发现此堆栈中每个元素的类型,具体取决于它们具有client()为您提供下一个元素的成员函数的类型。一旦找到合适的替换,您将创建它,保留堆栈中的所有下游元素。然后,您将Client使用NoDecorations构造函数重新创建一个。

于 2020-07-19T13:10:39.887 回答