Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient pipelining HTTP GET requests to ServiceStack API

First, I have ServiceStack as my server which provides RESTful HTTP API.

Here is an example.

public void GET(XXXXXRequest request)
{
    System.Threading.Thread.Sleep(2000);
}

Then I use System.Net.Http.HttpClient to access it. As it is said here, HttpClient is thread-safe for most of its methods to sending HTTP GET requests over the same TCP connection.

So I have a singleton instance of HttpClient as below

HttpClient _httpClient = new HttpClient(new WebRequestHandler()
{
    AllowPipelining = true
});

Then I use the following test code to send the request one after previous's response

await _httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
await _httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);

In smart sniffer, I do see the requests are sent in one connection and it goes like:

Client -> Request1
Client <- Response1
Client -> Request2
Client <- Response2
Client -> Request3
Client <- Response3

Now I change the code to fire-and-forget mode as below.

_httpClient.SendAsync(request1, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request2, HttpCompletionOption.ResponseContentRead);
_httpClient.SendAsync(request3, HttpCompletionOption.ResponseContentRead);

So that the requests are sent without waiting for previous reponse and I expect the requests & response go like below

Client -> Request1
Client -> Request2
Client -> Request3
Client <- Response1
Client <- Response2
Client <- Response3

This is HTTP pipeline and quite good for performance.

enter image description here

But from my test, I see 3 connections are established for each of the HTTP GET request and it does not work as I expected.

Regarding the AllowPipelining proeprty, MSDN says

An application uses the AllowPipelining property to indicate a preference for pipelined connections. When AllowPipelining is true, an application makes pipelined connections to the servers that support them.

So, I suppose HttpClient does support pipelining, and the problem is located in ServiceStack? Is there some options in ServiceStack to enable HTTP pipelining?

like image 462
Mr.Wang from Next Door Avatar asked Aug 13 '15 11:08

Mr.Wang from Next Door


1 Answers

Pipelining is done at a very low level, below IIS even (in the http.sys kernel mode driver). While I'm afraid I can't explain the behavior you're seeing, I can confidently say that ServiceStack is not on the hook for supporting it. It's an HttpHandler, whose only concern is how to process a request and return a response.

like image 172
Todd Menier Avatar answered Jan 04 '23 14:01

Todd Menier