Skip to content

Commit d377118

Browse files
committed
fix #2438 make sure we can cancel out of the async pieces in webrequest that do not take a cancellationtoken
1 parent 035e102 commit d377118

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/Elasticsearch.Net/Connection/HttpConnection.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ public virtual ElasticsearchResponse<TReturn> Request<TReturn>(RequestData reque
154154
return builder.ToResponse();
155155
}
156156

157+
158+
private static void RegisterApmTaskTimeout(IAsyncResult result, WebRequest request, RequestData requestData) =>
159+
ThreadPool.RegisterWaitForSingleObject(result.AsyncWaitHandle, TimeoutCallback, request, requestData.RequestTimeout, true);
160+
161+
private static void TimeoutCallback(object state, bool timedOut)
162+
{
163+
if (!timedOut) return;
164+
(state as WebRequest)?.Abort();
165+
}
166+
157167
public virtual async Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData) where TReturn : class
158168
{
159169
var builder = new ResponseBuilder<TReturn>(requestData);
@@ -164,7 +174,10 @@ public virtual async Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(
164174

165175
if (data != null)
166176
{
167-
using (var stream = await request.GetRequestStreamAsync().ConfigureAwait(false))
177+
var apmGetRequestStreamTask = Task.Factory.FromAsync(request.BeginGetRequestStream, request.EndGetRequestStream, null);
178+
RegisterApmTaskTimeout(apmGetRequestStreamTask, request, requestData);
179+
180+
using (var stream = await apmGetRequestStreamTask.ConfigureAwait(false))
168181
{
169182
if (requestData.HttpCompression)
170183
using (var zipStream = new GZipStream(stream, CompressionMode.Compress))
@@ -179,7 +192,10 @@ public virtual async Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(
179192
//Either the stream or the response object needs to be closed but not both although it won't
180193
//throw any errors if both are closed atleast one of them has to be Closed.
181194
//Since we expose the stream we let closing the stream determining when to close the connection
182-
var response = (HttpWebResponse)(await request.GetResponseAsync().ConfigureAwait(false));
195+
196+
var apmGetResponseTask = Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null);
197+
RegisterApmTaskTimeout(apmGetResponseTask, request, requestData);
198+
var response = (HttpWebResponse)(await apmGetResponseTask.ConfigureAwait(false));
183199
builder.StatusCode = (int)response.StatusCode;
184200
builder.Stream = response.GetResponseStream();
185201
// https://github.com/elastic/elasticsearch-net/issues/2311

0 commit comments

Comments
 (0)