Erlang inets のキープアライブ機能と ibrowse http クライアント (最新バージョン) について混乱しています。RFCによると:
8.1.2.2 Pipelining
A client that supports persistent connections MAY "pipeline" its
requests (i.e., send multiple requests without waiting for each
response). A server MUST send its responses to those requests in the
same order that the requests were received.
Clients which assume persistent connections and pipeline immediately
after connection establishment SHOULD be prepared to retry their
connection if the first pipelined attempt fails. If a client does
such a retry, it MUST NOT pipeline before it knows the connection is
persistent. Clients MUST also be prepared to resend their requests if
the server closes the connection before sending all of the
corresponding responses.
Clients SHOULD NOT pipeline requests using non-idempotent methods or
non-idempotent sequences of methods (see section 9.1.2). Otherwise, a
premature termination of the transport connection could lead to
indeterminate results. A client wishing to send a non-idempotent
request SHOULD wait to send that request until it has received the
response status for the previous request.
永続的な接続に基づいて、「パイプライン」と「キープアライブ」の 2 つのモードがあり、それらの違いは、「パイプライン」を使用すると、前の接続の応答を待たずに同じ接続で要求を送信できることです。 . つまり、「キープアライブ」を使用する場合、同じ接続で他のリクエストを送信する前に、各レスポンスを待つ必要があります。
その結果、「キープアライブ」の実装は次のようになるはずだと思いました。
%% each httpc_handler(gen_server) maintains a persistent connection
%% with type of keep-alive
httpc_handler:handle_request(Request, keepalive) ->
%% check if there is request not finished yet
case is_there_old_request() of
true -> queue:in(RQueue, Request);
%% then send the request
false -> gen_tcp:send(Request)
end.
httpc_handler:handle_response(Response) ->
send_back(Response),
case queue:out(RQueue) of
undefined -> ...;
%% send the next request
Request -> gen_tcp:send(Request), ...
end.
しかし実際には、inets と ibrowse の実装は次のようになります。
httpc_handler:handle_request(Request, keepalive) ->
%% send without check
gen_tcp:send(Request),
case is_there_old_request() of
true -> queue:in(RQueue, Request);
false -> ...
end.
httpc_handler:handle_response(Response) ->
send_back(Response),
case queue:out(RQueue) of
undefined -> ...;
Request -> receive_next_response
end.
実際にはべき等制限のない「パイプライン」モードだと思います。
それで、私はコードで何かを見逃したのですか、それとも RFC を誤解しただけですか?