[#98098] [Ruby master Feature#16824] Follow RubyGems naming conventions for the stdlib — shannonskipper@...

Issue #16824 has been reported by shan (Shannon Skipper).

14 messages 2020/05/01

[#98147] [Ruby master Feature#16832] Use #name rather than #inspect to build "uninitialized constant" error messages — jean.boussier@...

Issue #16832 has been reported by byroot (Jean Boussier).

20 messages 2020/05/06

[#98174] [Ruby master Bug#16837] Can we make Ruby 3.0 as fast as Ruby 2.7 with the new assertions? — takashikkbn@...

Issue #16837 has been reported by k0kubun (Takashi Kokubun).

10 messages 2020/05/07

[#98241] [Ruby master Bug#16845] Building Ruby with old existing system Ruby results in make error with ./tool/file2lastrev.rb — erik@...

Issue #16845 has been reported by ErikSwan (Erik Swan).

7 messages 2020/05/09

[#98256] [Ruby master Feature#16847] Cache instruction sequences by default — jean.boussier@...

Issue #16847 has been reported by byroot (Jean Boussier).

16 messages 2020/05/11

[#98257] [Ruby master Feature#16848] Allow callables in $LOAD_PATH — jean.boussier@...

Issue #16848 has been reported by byroot (Jean Boussier).

27 messages 2020/05/11

[#98318] [Ruby master Bug#16853] calling bla(hash, **kw) with a string-based hash passes the strings into **kw (worked < 2.7) — sylvain.joyeux@...4x.org

Issue #16853 has been reported by sylvain.joyeux (Sylvain Joyeux).

12 messages 2020/05/13

[#98355] [Ruby master Bug#16889] TracePoint.enable { ... } also activates the TracePoint for other threads, even outside the block — eregontp@...

Issue #16889 has been reported by Eregon (Benoit Daloze).

16 messages 2020/05/14

[#98363] [Ruby master Feature#16891] Restore Positional Argument to Keyword Conversion — merch-redmine@...

Issue #16891 has been reported by jeremyevans0 (Jeremy Evans).

23 messages 2020/05/14

[#98371] [Ruby master Feature#16894] Integer division for Ruby 3 — andrew@...

Issue #16894 has been reported by ankane (Andrew Kane).

18 messages 2020/05/15

[#98391] [Ruby master Bug#16896] MakeMakefile methods should be private — eregontp@...

Issue #16896 has been reported by Eregon (Benoit Daloze).

10 messages 2020/05/15

[#98396] [Ruby master Feature#16897] Can a Ruby 3.0 compatible general purpose memoizer be written in such a way that it matches Ruby 2 performance? — sam.saffron@...

Issue #16897 has been reported by sam.saffron (Sam Saffron).

25 messages 2020/05/16

[#98453] [Ruby master Bug#16904] rubygems: psych: superclass mismatch for class Mark (TypeError) — jaruga@...

Issue #16904 has been reported by jaruga (Jun Aruga).

18 messages 2020/05/20

[#98486] [Ruby master Bug#16908] Strange behaviour of Hash#shift when used with `default_proc`. — samuel@...

Issue #16908 has been reported by ioquatix (Samuel Williams).

14 messages 2020/05/23

[#98569] [Ruby master Bug#16921] s390x: ramdom test failures for timeout or segmentation fault — jaruga@...

Issue #16921 has been reported by jaruga (Jun Aruga).

9 messages 2020/05/29

[#98599] [Ruby master Bug#16926] Kernel#require does not load a feature twice when $LOAD_PATH has been modified spec fails only on 2.7 — eregontp@...

Issue #16926 has been reported by Eregon (Benoit Daloze).

12 messages 2020/05/31

[ruby-core:98561] [Ruby master Feature#16559] Net::HTTP#request injects "Connection: close" header if #started? is false, wasting HTTP server resources

From: merch-redmine@...
Date: 2020-05-28 19:37:48 UTC
List: ruby-core #98561
Issue #16559 has been updated by jeremyevans0 (Jeremy Evans).

Backport deleted (2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
ruby -v deleted (2.8.0-dev, 2.7.0, 2.6.5)
Assignee set to naruse (Yui NARUSE)
Tracker changed from Bug to Feature

I don't think this is a bug fix, this just makes a different tradeoff.  This can help cases where the computer you are connecting to is overloaded by TIME_WAIT sockets.  However, by the same token, it causes TIME_WAIT sockets to accumulate on the computer you are connecting from.

Consider a situation where you have a program that needs to get the root page for hundreds of thousands of websites.  It connects to a hundred web servers concurrently:

```ruby
100.times.map do
  Thread.new do
    loop do
      break unless domain_name = input_queue.pop
      net = Net::HTTP.new(domain_name)
      output_queue.push net.get('/')
    end
  end
end.each(&:join)
```

This approach works fine currently (assuming you add the necessary error handling), because `connection: close` will be set and the server will close the connection, so the client socket will not end up in TIME_WAIT.  With your change, `connection: close` will not be set, the client will close the connection, and all client sockets will end up in TIME_WAIT until 2MSL expires.

I'm not against the patch, as it would make things more consistent, and the backwards compatibility issues are small.  You can always set the `connection` header manually if you want specific behavior.  The net/http maintainer will have to decide if the change is worth it.



----------------------------------------
Feature #16559: Net::HTTP#request injects "Connection: close" header if #started? is false, wasting HTTP server resources
https://bugs.ruby-lang.org/issues/16559#change-85858

* Author: f3ndot (Justin Bull)
* Status: Open
* Priority: Normal
* Assignee: naruse (Yui NARUSE)
----------------------------------------
Hello,

There appears to be a bug in Net::HTTP#request (and thus #get, #post, etc.) on an instance that isn't explicitly started by the programmer (by invoking #start first, or by executing #request inside a block passed to #start).

Inspecting the source code, it reveals #request will recursively call itself inside a #start block if #started? is false. This is great and as I'd expect.

However in production and in a test setup I'm observing TCP socket connections on the server-side in the "TIME_WAIT" state, indicating the socket was never properly closed. Conversely, explicitly running #request inside a #start block yields no such behaviour.

Consider the following setup, assuming you have docker:

```
docker run --rm -it -p 8080:80/tcp --user root ubuntu
apt-get update && apt-get install net-tools watch nginx
service nginx start
watch 'netstat -tunapl'
```

Running this on your host machine:

``` ruby
net = Net::HTTP.new('localhost', 8080)
50.times { net.get('/') } # is bad
```

Will spawn 50 TCP connections on the server, and will all have on TIME_WAIT for 60 seconds (different *nix OSes have different times):

```
Every 2.0s: netstat -tunapl

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      791/nginx: master p
tcp        0      0 172.17.0.2:80           172.17.0.1:60772        TIME_WAIT   -
tcp        0      0 172.17.0.2:80           172.17.0.1:60732        TIME_WAIT   -
tcp        0      0 172.17.0.2:80           172.17.0.1:60812        TIME_WAIT   -
tcp        0      0 172.17.0.2:80           172.17.0.1:60778        TIME_WAIT   -
...
```

However running any of these incantations have no such result:

``` ruby
50.times { Net::HTTP.get(URI('http://localhost:8080/')) } # is OK
```

``` ruby
net = Net::HTTP.new('localhost', 8080)
net.start
50.times { net.get('/') } # is OK
net.finish
```

``` ruby
net = Net::HTTP.new('localhost', 8080)
50.times { net.start { net.get('/') } } # is OK
```

These TIME_WAIT connections matter because a server receiving many HTTP requests from clients using Net::HTTP in this fashion (as Faraday does[1]) the server will begin to oversaturate and timeout past a particular scale.

I've tested and reproduced this in 2.7 and 2.6.

[1]: https://github.com/lostisland/faraday/pull/1117

---Files--------------------------------
dont-default-connection-close.patch (3.77 KB)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next