Skip to content

Commit 883567f

Browse files
committed
Add proper Ractor support to URI
* Using a module to map scheme name to scheme class, which also works with Ractor. * No constant redefinition, no ObjectSpace, still fast lookup for initial schemes.
1 parent b959da2 commit 883567f

File tree

12 files changed

+60
-18
lines changed

12 files changed

+60
-18
lines changed

lib/uri.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# class RSYNC < Generic
3131
# DEFAULT_PORT = 873
3232
# end
33-
# @@schemes['RSYNC'] = RSYNC
33+
# register_scheme 'RSYNC', RSYNC
3434
# end
3535
# #=> URI::RSYNC
3636
#
@@ -100,3 +100,9 @@ module URI
100100
require_relative 'uri/ldap'
101101
require_relative 'uri/ldaps'
102102
require_relative 'uri/mailto'
103+
104+
module URI
105+
INITIAL_SCHEMES = scheme_list
106+
private_constant :INITIAL_SCHEMES
107+
Ractor.make_shareable(INITIAL_SCHEMES) if defined?(Ractor)
108+
end

lib/uri/common.rb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ module URI
1616
REGEXP = RFC2396_REGEXP
1717
Parser = RFC2396_Parser
1818
RFC3986_PARSER = RFC3986_Parser.new
19+
Ractor.make_shareable(RFC3986_PARSER) if defined?(Ractor)
1920

2021
# URI::Parser.new
2122
DEFAULT_PARSER = Parser.new
@@ -27,6 +28,7 @@ module URI
2728
DEFAULT_PARSER.regexp.each_pair do |sym, str|
2829
const_set(sym, str)
2930
end
31+
Ractor.make_shareable(DEFAULT_PARSER) if defined?(Ractor)
3032

3133
module Util # :nodoc:
3234
def make_components_hash(klass, array_hash)
@@ -62,22 +64,33 @@ def make_components_hash(klass, array_hash)
6264

6365
include REGEXP
6466

65-
@@schemes = {}
67+
module Schemes
68+
end
69+
private_constant :Schemes
70+
71+
def self.register_scheme(scheme, klass)
72+
Schemes.const_set(scheme, klass)
73+
end
74+
6675
# Returns a Hash of the defined schemes.
6776
def self.scheme_list
68-
@@schemes
77+
Schemes.constants.map { |name|
78+
[name.to_s.upcase, Schemes.const_get(name)]
79+
}.to_h
6980
end
7081

7182
#
7283
# Construct a URI instance, using the scheme to detect the appropriate class
7384
# from +URI.scheme_list+.
7485
#
7586
def self.for(scheme, *arguments, default: Generic)
76-
if scheme
77-
uri_class = @@schemes[scheme.upcase] || default
78-
else
79-
uri_class = default
87+
const_name = scheme.to_s.upcase
88+
89+
uri_class = INITIAL_SCHEMES[const_name]
90+
if !uri_class && !const_name.empty? && Schemes.const_defined?(const_name, false)
91+
uri_class = Schemes.const_get(const_name, false)
8092
end
93+
uri_class ||= default
8194

8295
return uri_class.new(scheme, *arguments)
8396
end
@@ -653,6 +666,7 @@ def self.decode_www_form(str, enc=Encoding::UTF_8, separator: '&', use__charset_
653666
"utf-16"=>"utf-16le",
654667
"utf-16le"=>"utf-16le",
655668
} # :nodoc:
669+
Ractor.make_shareable(WEB_ENCODINGS_) if defined?(Ractor)
656670

657671
# :nodoc:
658672
# return encoding or nil

lib/uri/file.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,5 +90,5 @@ def set_password(v)
9090
end
9191
end
9292

93-
@@schemes['FILE'] = File
93+
register_scheme 'FILE', File
9494
end

lib/uri/ftp.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,5 +262,6 @@ def to_s
262262
return str
263263
end
264264
end
265-
@@schemes['FTP'] = FTP
265+
266+
register_scheme 'FTP', FTP
266267
end

lib/uri/http.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,5 @@ def request_uri
8282
end
8383
end
8484

85-
@@schemes['HTTP'] = HTTP
86-
85+
register_scheme 'HTTP', HTTP
8786
end

lib/uri/https.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@ class HTTPS < HTTP
1818
# A Default port of 443 for URI::HTTPS
1919
DEFAULT_PORT = 443
2020
end
21-
@@schemes['HTTPS'] = HTTPS
21+
22+
register_scheme 'HTTPS', HTTPS
2223
end

lib/uri/ldap.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,5 +257,5 @@ def hierarchical?
257257
end
258258
end
259259

260-
@@schemes['LDAP'] = LDAP
260+
register_scheme 'LDAP', LDAP
261261
end

lib/uri/ldaps.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ class LDAPS < LDAP
1717
# A Default port of 636 for URI::LDAPS
1818
DEFAULT_PORT = 636
1919
end
20-
@@schemes['LDAPS'] = LDAPS
20+
21+
register_scheme 'LDAPS', LDAPS
2122
end

lib/uri/mailto.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,5 +289,5 @@ def to_mailtext
289289
alias to_rfc822text to_mailtext
290290
end
291291

292-
@@schemes['MAILTO'] = MailTo
292+
register_scheme 'MAILTO', MailTo
293293
end

lib/uri/ws.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,5 @@ def request_uri
7979
end
8080
end
8181

82-
@@schemes['WS'] = WS
83-
82+
register_scheme 'WS', WS
8483
end

0 commit comments

Comments
 (0)