1

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 を誤解しただけですか?

4

2 に答える 2

2

inets httpc: Corrected separation of pipelining and ..この問題は、Erlang/OTP R16の commit によって既に修正されています。

于 2013-03-13T14:26:24.960 に答える
0

最新の OTP ソースを見ると、冪等ロジックは実際にはhttpc_manager:select_session. リクエストがべき等でない場合は を返しno_connection、システムに新しい接続を作成するように促します。全体にさらにロジックが散在していますが、パイプライン処理とキープアライブを処理するための個別の関数を特定しましたhttpc_handler

于 2013-01-24T04:16:24.960 に答える