cowboy_static / file:sendfile

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

cowboy_static / file:sendfile

Steve Strong
Hi,

I’m seeing a potential issue with file:sendfile if the client shuts down the connection.  My setup is a cowboy server with a simple cowboy_static endpoint, and a rate-limited curl as the client - if I start the curl download and then ctrl-c curl before it completes, cowboy sits hung inside the call to sendfile.  

I inspected the cowboy process as follows:

([hidden email])83> P = processes().
[<0.0.0>,<0.1.0>,<0.2.0>,<0.3.0>,<0.4.0>,<0.5.0>,<0.8.0>,
 <0.40.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.47.0>,<0.48.0>,
 <0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,<0.54.0>,<0.55.0>,
 <0.56.0>,<0.57.0>,<0.58.0>,<0.59.0>,<0.60.0>,<0.61.0>,
 <0.62.0>,<0.63.0>,<0.64.0>,<0.65.0>|…]

%% Run curl and ctrl-c in a separate window…

([hidden email])84> erlang:process_info(hd(processes() -- P), [current_function, messages]).
[{current_function,{prim_inet,sendfile_1,4}},
 {messages,[{'EXIT',<0.1798.0>,normal},
            {tcp_closed,#Port<0.266>},
            {inet_reply,#Port<0.266>,{error,closed}}]}]


This process looks doomed to live forever - it is stuck in prim_inet:sendfile_1 on the following receive:

      receive
        {sendfile, S, {ok, SentLow, SentHigh}} ->
          {ok, SentLow bor (SentHigh bsl 32)};
        {sendfile, S, {error, Reason}} ->
          {error, Reason};
        {'EXIT', S, _Reason} ->
          {error, closed}
      end

The port that it had opened, 0.266, has closed so there will never be an exit message:

([hidden email])89> erlang:ports().
[#Port<0.0>,#Port<0.2>,#Port<0.4>,#Port<0.5>,#Port<0.6>,
 #Port<0.8>,#Port<0.10>,#Port<0.11>,#Port<0.12>,#Port<0.13>,
 #Port<0.14>,#Port<0.15>,#Port<0.16>,#Port<0.254>,
 #Port<0.255>,#Port<0.256>,#Port<0.257>,#Port<0.258>,
 #Port<0.259>,#Port<0.260>,#Port<0.261>,#Port<0.262>,
 #Port<0.263>,#Port<0.264>]

I’m guessing the process wasn’t linked with the port, or it would have received the exit message and all would have been well.  Unsure if this is a cowboy or prim_inet bug, or indeed if I’ve done something wrong.  Any ideas?

Cheers,

Steve



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: cowboy_static / file:sendfile

Loïc Hoguin-3
Hello,

This might have been fixed in OTP-21.2:

   OTP-15461    Application(s): erts
                Related Id(s): ERL-784

                Fixed bug in file:sendfile when the send operation
                failed. For sockets in active modes it could cause
                emulator crash or a hanging call. For sockets with
                {active,false} an unexpected {inet_reply, _, _} message
                could be sent to the calling process. The bug exists
                since OTP-21.0.

On 12/12/18 4:40 PM, Steve Strong wrote:

> Hi,
>
> I’m seeing a potential issue with file:sendfile if the client shuts down
> the connection.  My setup is a cowboy server with a simple cowboy_static
> endpoint, and a rate-limited curl as the client - if I start the curl
> download and then ctrl-c curl before it completes, cowboy sits hung
> inside the call to sendfile.
>
> I inspected the cowboy process as follows:
>
> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)83> P = processes().
> [<0.0.0>,<0.1.0>,<0.2.0>,<0.3.0>,<0.4.0>,<0.5.0>,<0.8.0>,
>   <0.40.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.47.0>,<0.48.0>,
>   <0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,<0.54.0>,<0.55.0>,
>   <0.56.0>,<0.57.0>,<0.58.0>,<0.59.0>,<0.60.0>,<0.61.0>,
>   <0.62.0>,<0.63.0>,<0.64.0>,<0.65.0>|…]
>
> %% Run curl and ctrl-c in a separate window…
>
> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)84>
> erlang:process_info(hd(processes() -- P), [current_function, messages]).
> [{current_function,{prim_inet,sendfile_1,4}},
>   {messages,[{'EXIT',<0.1798.0>,normal},
>              {tcp_closed,#Port<0.266>},
>              {inet_reply,#Port<0.266>,{error,closed}}]}]
>
>
> This process looks doomed to live forever - it is stuck in
> prim_inet:sendfile_1 on the following receive:
>
>        receive
>          {sendfile, S, {ok, SentLow, SentHigh}} ->
>            {ok, SentLow bor (SentHigh bsl 32)};
>          {sendfile, S, {error, Reason}} ->
>            {error, Reason};
>          {'EXIT', S, _Reason} ->
>            {error, closed}
>        end
>
> The port that it had opened, 0.266, has closed so there will never be an
> exit message:
>
> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)89> erlang:ports().
> [#Port<0.0>,#Port<0.2>,#Port<0.4>,#Port<0.5>,#Port<0.6>,
>   #Port<0.8>,#Port<0.10>,#Port<0.11>,#Port<0.12>,#Port<0.13>,
>   #Port<0.14>,#Port<0.15>,#Port<0.16>,#Port<0.254>,
>   #Port<0.255>,#Port<0.256>,#Port<0.257>,#Port<0.258>,
>   #Port<0.259>,#Port<0.260>,#Port<0.261>,#Port<0.262>,
>   #Port<0.263>,#Port<0.264>]
>
> I’m guessing the process wasn’t linked with the port, or it would have
> received the exit message and all would have been well.  Unsure if this
> is a cowboy or prim_inet bug, or indeed if I’ve done something wrong.
>   Any ideas?
>
> Cheers,
>
> Steve
>
>
>
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
>

--
Loïc Hoguin
https://ninenines.eu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: cowboy_static / file:sendfile

Steve Strong
Yes, 21.2 appears to have solved it - thanks!

> On 12 Dec 2018, at 15:52, Loïc Hoguin <[hidden email]> wrote:
>
> Hello,
>
> This might have been fixed in OTP-21.2:
>
>  OTP-15461    Application(s): erts
>               Related Id(s): ERL-784
>
>               Fixed bug in file:sendfile when the send operation
>               failed. For sockets in active modes it could cause
>               emulator crash or a hanging call. For sockets with
>               {active,false} an unexpected {inet_reply, _, _} message
>               could be sent to the calling process. The bug exists
>               since OTP-21.0.
>
> On 12/12/18 4:40 PM, Steve Strong wrote:
>> Hi,
>> I’m seeing a potential issue with file:sendfile if the client shuts down the connection.  My setup is a cowboy server with a simple cowboy_static endpoint, and a rate-limited curl as the client - if I start the curl download and then ctrl-c curl before it completes, cowboy sits hung inside the call to sendfile.
>> I inspected the cowboy process as follows:
>> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)83> P = processes().
>> [<0.0.0>,<0.1.0>,<0.2.0>,<0.3.0>,<0.4.0>,<0.5.0>,<0.8.0>,
>>  <0.40.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.47.0>,<0.48.0>,
>>  <0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,<0.54.0>,<0.55.0>,
>>  <0.56.0>,<0.57.0>,<0.58.0>,<0.59.0>,<0.60.0>,<0.61.0>,
>>  <0.62.0>,<0.63.0>,<0.64.0>,<0.65.0>|…]
>> %% Run curl and ctrl-c in a separate window…
>> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)84> erlang:process_info(hd(processes() -- P), [current_function, messages]).
>> [{current_function,{prim_inet,sendfile_1,4}},
>>  {messages,[{'EXIT',<0.1798.0>,normal},
>>             {tcp_closed,#Port<0.266>},
>>             {inet_reply,#Port<0.266>,{error,closed}}]}]
>> This process looks doomed to live forever - it is stuck in prim_inet:sendfile_1 on the following receive:
>>       receive
>>         {sendfile, S, {ok, SentLow, SentHigh}} ->
>>           {ok, SentLow bor (SentHigh bsl 32)};
>>         {sendfile, S, {error, Reason}} ->
>>           {error, Reason};
>>         {'EXIT', S, _Reason} ->
>>           {error, closed}
>>       end
>> The port that it had opened, 0.266, has closed so there will never be an exit message:
>> (file_encoder@127.0.0.1 <mailto:file_encoder@127.0.0.1>)89> erlang:ports().
>> [#Port<0.0>,#Port<0.2>,#Port<0.4>,#Port<0.5>,#Port<0.6>,
>>  #Port<0.8>,#Port<0.10>,#Port<0.11>,#Port<0.12>,#Port<0.13>,
>>  #Port<0.14>,#Port<0.15>,#Port<0.16>,#Port<0.254>,
>>  #Port<0.255>,#Port<0.256>,#Port<0.257>,#Port<0.258>,
>>  #Port<0.259>,#Port<0.260>,#Port<0.261>,#Port<0.262>,
>>  #Port<0.263>,#Port<0.264>]
>> I’m guessing the process wasn’t linked with the port, or it would have received the exit message and all would have been well.  Unsure if this is a cowboy or prim_inet bug, or indeed if I’ve done something wrong.   Any ideas?
>> Cheers,
>> Steve
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://erlang.org/mailman/listinfo/erlang-questions
>
> --
> Loïc Hoguin
> https://ninenines.eu

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions