Skip to content

Commit f32c59e

Browse files
authored
Better http request timeout handling. (aspnet#37)
1 parent bcea094 commit f32c59e

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

src/signalrclient/default_http_client.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,41 @@ namespace signalr
4444
http_request.headers() = headers;
4545
}
4646

47-
auto milliseconds = std::chrono::milliseconds(request.timeout);
47+
#pragma warning (push)
48+
#pragma warning (disable : 4625 4626 5026 5027)
49+
struct cancel_wait_context
50+
{
51+
bool complete = false;
52+
std::condition_variable cv;
53+
std::mutex mtx;
54+
};
55+
#pragma warning (pop)
56+
57+
std::shared_ptr<cancel_wait_context> context;
4858
pplx::cancellation_token_source cts;
59+
60+
auto milliseconds = std::chrono::milliseconds(request.timeout);
4961
if (milliseconds.count() != 0)
5062
{
51-
pplx::create_task([milliseconds, cts]()
63+
context = std::make_shared<cancel_wait_context>();
64+
pplx::create_task([context, milliseconds, cts]()
5265
{
53-
std::this_thread::sleep_for(milliseconds);
54-
cts.cancel();
66+
auto timeout_point = std::chrono::steady_clock::now() + milliseconds;
67+
std::unique_lock<std::mutex> lck(context->mtx);
68+
while (!context->complete)
69+
{
70+
if (context->cv.wait_until(lck, timeout_point) == std::cv_status::timeout)
71+
{
72+
cts.cancel();
73+
break;
74+
}
75+
}
5576
});
5677
}
5778

5879
web::http::client::http_client client(utility::conversions::to_string_t(url));
5980
client.request(http_request, cts.get_token())
60-
.then([callback](pplx::task<web::http::http_response> response_task)
81+
.then([context, callback](pplx::task<web::http::http_response> response_task)
6182
{
6283
try
6384
{
@@ -76,6 +97,13 @@ namespace signalr
7697
{
7798
callback(http_response(), std::current_exception());
7899
}
100+
101+
if (context != nullptr)
102+
{
103+
std::unique_lock<std::mutex> lck(context->mtx);
104+
context->complete = true;
105+
context->cv.notify_all();
106+
}
79107
});
80108
}
81109
}

src/signalrclient/negotiate.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ namespace signalr
3434
http_request request;
3535
request.method = http_method::POST;
3636
request.headers = config.get_http_headers();
37+
#ifdef USE_CPPRESTSDK
38+
request.timeout = config.get_http_client_config().timeout();
39+
#endif
3740

3841
client.send(negotiate_url, request, [callback](const http_response& http_response, std::exception_ptr exception)
3942
{

0 commit comments

Comments
 (0)