Skip to content

Instantly share code, notes, and snippets.

@niku
Last active June 28, 2025 12:02
Show Gist options
  • Save niku/574badbfc1158ef534943ce402d8264e to your computer and use it in GitHub Desktop.
Save niku/574badbfc1158ef534943ce402d8264e to your computer and use it in GitHub Desktop.
move socket across Ractor
~ ()
ruby --version
ruby 3.5.0dev (2025-06-27T15:03:42Z master 0828dff3f8) +PRISM [arm64-darwin24]
~ ()
bat socket_move_sandbox.rb
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: socket_move_sandbox.rb
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ require "socket"
2 │
3 │ tcp_server = TCPServer.new(0)
4 │ port = tcp_server.addr[1]
5 │
6 │ Thread.start do
7 │ Socket.accept_loop(tcp_server) do |c1|
8 │ p 1, c1
9 │
10 │ r = Ractor.new do
11 │ c2 = Ractor.receive
12 │ p 2, c2
13 │ c2
14 │ end
15 │
16 │ r.send(c1, move: true) # move: true is important here to transfer ownership of the socket
17 │
18 │ c3 = r.value
19 │ p 3, c3
20 │
21 │ c3.close
22 │ end
23 │ end
24 │
25 │ t = TCPSocket.new("localhost", port)
26 │ t.close
27 │
28 │ sleep 1
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
~ ()
ruby socket_move_sandbox.rb
1
#<TCPSocket:fd 8, AF_INET6, ::1, 51633>
socket_move_sandbox.rb:10: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
2
#<TCPSocket:fd 8, AF_INET6, ::1, 51633>
3
#<TCPSocket:fd 8, AF_INET6, ::1, 51633>
~ ()
ruby --version
ruby 3.5.0dev (2025-06-27T15:03:42Z master 0828dff3f8) +PRISM [arm64-darwin24]
~ ()
bat socket_move_sandbox.rb
───────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: socket_move_sandbox.rb
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ require "socket"
2 │
3 │ tcp_server = TCPServer.new(0)
4 │ port = tcp_server.addr[1]
5 │
6 │ Thread.start do
7 │ Socket.accept_loop(tcp_server) do |c1|
8 │ p 1, c1
9 │
10 │ r = Ractor.new do
11 │ c2 = Ractor.receive
12 │ p 2, c2
13 │ c2
14 │ end
15 │
16 │ r.send(c1)
17 │
18 │ c3 = r.value
19 │ p 3, c3
20 │
21 │ c3.close
22 │ end
23 │ end
24 │
25 │ t = TCPSocket.new("localhost", port)
26 │ t.close
27 │
28 │ sleep 1
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
~ ()
ruby socket_move_sandbox.rb
1
#<TCPSocket:fd 8, AF_INET6, ::1, 51679>
socket_move_sandbox.rb:10: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
2
#<TCPSocket:fd 9, AF_INET6, ::1, 51679>
3
#<TCPSocket:fd 9, AF_INET6, ::1, 51679>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment