| Age | Commit message (Collapse) | Author |
|
|
|
|
|
tempfile.gemspec
|
|
https://github.com/ruby/prism/commit/e1a9a1d478
|
|
In the following code, the iclass tree of refinements in cref should be <iclass of Kernel@M2> -> <iclass of Kernel@M1> -> Kernel.
However, the iclass tree was broken because of code for included modules of refinements in rb_using_refinement().
Refinement#include is now removed, so this commit removes such unnecessary code.
```ruby
module M1
refine(Kernel) do
def f1 = :f1
end
end
module M2
refine(Kernel) do
def f2 = :f2
end
end
class Foo
using M1
using M2
def test
p f2 #=> :f2
p f1 # expected => :f1
# actual => undefined local variable or method 'f1' for an instance of Foo
end
end
Foo.new.test
```
|
|
This bug demonstrates the issue I reported. It passes on commit
https://github.com/ruby/ruby/commit/114e71d06280f9c57b9859ee4405ae89a989ddb6
but does not pass on commit (the immediate child of the above commit)
https://github.com/ruby/ruby/commit/1d2d25dcadda0764f303183ac091d0c87b432566
|
|
https://github.com/ruby/prism/commit/959eb506ca
|
|
specification attribute.
https://github.com/rubygems/rubygems/commit/e4bb33747a
|
|
Fixes [Bug #5179]
|
|
'vendored_' prefix
https://github.com/rubygems/rubygems/commit/cfc908c8c1
|
|
Bumps [rb-sys](https://github.com/oxidize-rb/rb-sys) from 0.9.88 to 0.9.89.
- [Release notes](https://github.com/oxidize-rb/rb-sys/releases)
- [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.88...v0.9.89)
---
updated-dependencies:
- dependency-name: rb-sys
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
https://github.com/rubygems/rubygems/commit/75e5ec62be
|
|
Bumps [rb-sys](https://github.com/oxidize-rb/rb-sys) from 0.9.88 to 0.9.89.
- [Release notes](https://github.com/oxidize-rb/rb-sys/releases)
- [Commits](https://github.com/oxidize-rb/rb-sys/compare/v0.9.88...v0.9.89)
---
updated-dependencies:
- dependency-name: rb-sys
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
https://github.com/rubygems/rubygems/commit/94e6907098
|
|
https://github.com/ruby/prism/commit/8ea7a3270f
|
|
integers
(https://github.com/ruby/strscan/pull/89)
This commit adds `scan_byte` and `peek_byte`. `scan_byte` will scan the
current byte, return it as an integer, and advance the cursor.
`peek_byte` will return the current byte as an integer without advancing
the cursor.
Currently `StringScanner#get_byte` returns a string, but I want to get
the current byte without allocating a string. I think this will help
with writing high performance lexers.
---------
https://github.com/ruby/strscan/commit/873aba2e5d
Co-authored-by: Sutou Kouhei <kou@clear-code.com>
|
|
Windows disallows to unlink opened files.
https://github.com/rubygems/rubygems/commit/e0b63754bf
|
|
On Windows, open files cannot be removed and `FileUtils.rm_rf` just
silently fails. This means also handle leaks, not only temporary file
leaks.
https://github.com/rubygems/rubygems/commit/80a9c3ec08
|
|
This is a fix-up of #7483.
Test method names in Rubygems are often very long, and the path under
the temporary directory generated from them can easily exceed system
limits.
Even without including the method name in the path name, by saving the
method and path name pair, it is possible to find the method from the
remaining path name.
https://github.com/rubygems/rubygems/commit/de55064a3d
|
|
This reverts commit 6aa5067ab970e70693529cde5102fab587158f7f.
|
|
|
|
|
|
* Introduction of Happy Eyeballs Version 2 (RFC8305) in Socket.tcp
This is an implementation of Happy Eyeballs version 2 (RFC 8305) in Socket.tcp.
[Background]
Currently, `Socket.tcp` synchronously resolves names and makes connection attempts with `Addrinfo::foreach.`
This implementation has the following two problems.
1. In name resolution, the program stops until the DNS server responds to all DNS queries.
2. In a connection attempt, while an IP address is trying to connect to the destination host and is taking time, the program stops, and other resolved IP addresses cannot try to connect.
[Proposal]
"Happy Eyeballs" ([RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305)) is an algorithm to solve this kind of problem. It avoids delays to the user whenever possible and also uses IPv6 preferentially.
I implemented it into `Socket.tcp` by using `Addrinfo.getaddrinfo` in each thread spawned per address family to resolve the hostname asynchronously, and using `Socket::connect_nonblock` to try to connect with multiple addrinfo in parallel.
[Outcome]
This change eliminates a fatal defect in the following cases.
Case 1. One of the A or AAAA DNS queries does not return
---
require 'socket'
class Addrinfo
class << self
# Current Socket.tcp depends on foreach
def foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block)
getaddrinfo(nodename, service, Socket::AF_INET6, socktype, protocol, flags, timeout: timeout)
.concat(getaddrinfo(nodename, service, Socket::AF_INET, socktype, protocol, flags, timeout: timeout))
.each(&block)
end
def getaddrinfo(_, _, family, *_)
case family
when Socket::AF_INET6 then sleep
when Socket::AF_INET then [Addrinfo.tcp("127.0.0.1", 4567)]
end
end
end
end
Socket.tcp("localhost", 4567)
---
Because the current `Socket.tcp` cannot resolve IPv6 names, the program stops in this case. It cannot start to connect with IPv4 address.
Though `Socket.tcp` with HEv2 can promptly start a connection attempt with IPv4 address in this case.
Case 2. Server does not promptly return ack for syn of either IPv4 / IPv6 address family
---
require 'socket'
fork do
socket = Socket.new(Socket::AF_INET6, :STREAM)
socket.setsockopt(:SOCKET, :REUSEADDR, true)
socket.bind(Socket.pack_sockaddr_in(4567, '::1'))
sleep
socket.listen(1)
connection, _ = socket.accept
connection.close
socket.close
end
fork do
socket = Socket.new(Socket::AF_INET, :STREAM)
socket.setsockopt(:SOCKET, :REUSEADDR, true)
socket.bind(Socket.pack_sockaddr_in(4567, '127.0.0.1'))
socket.listen(1)
connection, _ = socket.accept
connection.close
socket.close
end
Socket.tcp("localhost", 4567)
---
The current `Socket.tcp` tries to connect serially, so when its first name resolves an IPv6 address and initiates a connection to an IPv6 server, this server does not return an ACK, and the program stops.
Though `Socket.tcp` with HEv2 starts to connect sequentially and in parallel so a connection can be established promptly at the socket that attempted to connect to the IPv4 server.
In exchange, the performance of `Socket.tcp` with HEv2 will be degraded.
---
100.times { Socket.tcp("www.ruby-lang.org", 80) }
---
This is due to the addition of the creation of IO objects, Thread objects, etc., and calls to `IO::select` in the implementation.
* Avoid NameError of Socket::EAI_ADDRFAMILY in MinGW
* Support Windows with SO_CONNECT_TIME
* Improve performance
I have additionally implemented the following patterns:
- If the host is single-stack, name resolution is performed in the main thread. This reduces the cost of creating threads.
- If an IP address is specified, name resolution is performed in the main thread. This also reduces the cost of creating threads.
- If only one IP address is resolved, connect is executed in blocking mode. This reduces the cost of calling IO::select.
Also, I have added a fast_fallback option for users who wish not to use HE.
Here are the results of each performance test.
```ruby
require 'socket'
require 'benchmark'
HOSTNAME = "www.ruby-lang.org"
PORT = 80
ai = Addrinfo.tcp(HOSTNAME, PORT)
Benchmark.bmbm do |x|
x.report("Domain name") do
30.times { Socket.tcp(HOSTNAME, PORT).close }
end
x.report("IP Address") do
30.times { Socket.tcp(ai.ip_address, PORT).close }
end
x.report("fast_fallback: false") do
30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close }
end
end
```
```
user system total real
Domain name 0.015567 0.032511 0.048078 ( 0.325284)
IP Address 0.004458 0.014219 0.018677 ( 0.284361)
fast_fallback: false 0.005869 0.021511 0.027380 ( 0.321891)
````
And this is the measurement result when executed in a single stack environment.
```
user system total real
Domain name 0.007062 0.019276 0.026338 ( 1.905775)
IP Address 0.004527 0.012176 0.016703 ( 3.051192)
fast_fallback: false 0.005546 0.019426 0.024972 ( 1.775798)
```
The following is the result of the run on Ruby 3.3.0.
(on Dual stack environment)
```
user system total real
Ruby 3.3.0 0.007271 0.027410 0.034681 ( 0.472510)
```
(on Single stack environment)
```
user system total real
Ruby 3.3.0 0.005353 0.018898 0.024251 ( 1.774535)
```
* Do not cache `Socket.ip_address_list`
As mentioned in the comment at https://github.com/ruby/ruby/pull/9374#discussion_r1482269186, caching Socket.ip_address_list does not follow changes in network configuration.
But if we stop caching, it becomes necessary to check every time `Socket.tcp` is called whether it's a single stack or not, which could further degrade performance in the case of a dual stack.
From this, I've changed the approach so that when a domain name is passed, it doesn't check whether it's a single stack or not and resolves names in parallel each time.
The performance measurement results are as follows.
require 'socket'
require 'benchmark'
HOSTNAME = "www.ruby-lang.org"
PORT = 80
ai = Addrinfo.tcp(HOSTNAME, PORT)
Benchmark.bmbm do |x|
x.report("Domain name") do
30.times { Socket.tcp(HOSTNAME, PORT).close }
end
x.report("IP Address") do
30.times { Socket.tcp(ai.ip_address, PORT).close }
end
x.report("fast_fallback: false") do
30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close }
end
end
user system total real
Domain name 0.004085 0.011873 0.015958 ( 0.330097)
IP Address 0.000993 0.004400 0.005393 ( 0.257286)
fast_fallback: false 0.001348 0.008266 0.009614 ( 0.298626)
* Wait forever if fallback addresses are unresolved, unless resolv_timeout
Changed from waiting only 3 seconds for name resolution when there is no fallback address available, to waiting as long as there is no resolv_timeout.
This is in accordance with the current `Socket.tcp` specification.
* Use exact pattern to match IPv6 address format for specify address family
|
|
|
|
|
|
https://github.com/ruby/prism/commit/fa9a30ad91
|
|
In a method definition, the `begin` may not have an `nd_body`. When that
happens we get a null expr back from `last_expr_node` which causes a
segv for the following examples:
```ruby
def (begin;end).foo; end
def (begin;else;end).foo; end
def (begin;ensure;else;end).foo; end
```
In addition, I've added tests for other cases that weren't causing a
segv but appeared untested.`
Fixes https://bugs.ruby-lang.org/issues/20234
|
|
https://github.com/ruby/prism/commit/377666a5df
|
|
https://github.com/ruby/prism/commit/865b0d5fbe
|
|
https://github.com/ruby/prism/commit/3e10c46c14
|
|
https://github.com/ruby/optparse/commit/07e83673a8
|
|
https://github.com/ruby/prism/commit/9137226a52
|
|
|
|
https://github.com/ruby/prism/commit/120d8c0479
|
|
https://github.com/ruby/prism/commit/a6a552411c
|
|
|
|
|
|
|
|
|
|
Only consider it eof if we read ahead and something fills the buf.
If not, we may only have empty blocks and the footer.
Fixes https://github.com/ruby/zlib/pull/56
https://github.com/ruby/zlib/commit/437bea8003
|
|
So that compilers know they need to add to add an anonymous
variable to the local table.
https://github.com/ruby/prism/commit/7f1aadd057
|
|
Previously, `StackOperand`s caching `sp_offset` was held across a
jit_prepare_call_with_gc(), which invalidates the offsets. With the
right register allocation state, the canary overlapped with the old
address of the receiver and YJIT clobbered the receiver writing the
canary.
|
|
https://github.com/ruby/prism/commit/ea7e400f85
|
|
|
|
https://github.com/rubygems/rubygems/commit/52de6eccf5
|
|
https://github.com/rubygems/rubygems/commit/148deade0a
|
|
The method which prints single pair of a hash, to make extending
pretty printing Hash easier, apart from Hash construct itself.
https://github.com/ruby/pp/commit/3fcf2d1142
|
|
So that the `pp` method can work in inherited classes with that
class.
https://github.com/ruby/pp/commit/f204df3aad
|
|
https://github.com/ruby/pp/commit/f5cee21a1e
|
|
It's been 2 years since ruby/date#49, so it's okay.
https://github.com/ruby/date/commit/435dfec6c8
|
|
|
|
|