Rabbit Slide Show

Ruby, Ractor, QUIC





Page: 1

Ruby, Ractor, QUIC
unasuke (Yusuke Nakamura)
RubyKaigi Takeout 2021

Page: 2

Self introduction
Name: unasuke (Yusuke Nakamura)
Work: freelance Web app developer
OOParts (Cloud Gaming Service) backend dev
Itamae gem maintainer, Kaigi on Rails staff
GitHub https://github.com/unasuke
Mastodon https://mstdn.unasuke.com/@unasuke
Twitter https://twitter.com/yu_suke1994

Page: 3

Next generation Web
widespreading Web usage
Cloud Gaming
Video meeting
Streaming media
We want the Web to be faster!

Page: 4

Cloud Gaming requiement
"real-time bidirectional communication"
1. Send player's input to the game on the cloud machine
2. The game render the input result
3. Send result to the player's screen (web browser)
Repeat the above process as soon as possible for comfortable game play.
(Same as remote working collaboration)

Page: 5

Way to real-time bidirectional communication on the Web
a new server-client protocol over the HTTP/3
use UDP
status: draft → https://datatracker.ietf.org/group/webtrans/documents/

Page: 6

A new hyper text transfer protocol (draft)
This document defines HTTP/3, a mapping of HTTP semantics over the
QUIC transport protocol
"QUIC" ? What is this?

Page: 7

standardized at 2021-05-27 by IETF
More faster than HTTP/2
Using UDP, not TCP

Page: 8

Tweet by ko1

Page: 9

Tweet by ko1
two people
@_ko1 (Koichi Sasada)
Ruby core commiter
Ractor author
@kazuho (Kazuho Oku)
author of h2o
QUIC RFC contributor
Sounds interesting!

Page: 10

What, Why QUIC
TCP is reliable, but slow
Oriented data transfer
Retransmission of lost packets
Congestion control
UDP is unreliable, but fast
realtime transfer e.g. audio

Page: 11

What, Why QUIC - TCP's problem
Three way handshake
additional TLS handshake (at secure communication)
Head-of-Line Blocking (HoLB)
QUIC is a new latency-reducing, reliable, and secure internet transport

Page: 12

Is there a benefit?
Why imprement QUIC on Ruby?
1. For my study and interest
2. For Ractor
There are still few examples of Ractor
helps evaluation and improvement of Ractor
e.g. https://github.com/mame/optcarrot

Page: 13

QUIC - Initial Packet (RFC9001 Appendix A)

Page: 14

QUIC - reading Initial Packet

Page: 15

QUIC - reading Initial Packet

Page: 16

QUIC - reading Initial Packet

Page: 17

QUIC - reading Initial Packet

Page: 18

QUIC - reading Initial Packet

Page: 19

QUIC - reading Initial Packet

Page: 20

n月刊ラムダノート Vol.2, No.1(2020)
#1 パケットの設計から見るQUIC(西田佳史)

Page: 21

QUIC - reading Initial Packet by Ruby

Page: 22

QUIC - reading Initial Packet by Ruby
It causes Ractor::IsolationError when use in not main Ractor

Page: 23

QUIC - reading Initial Packet by Ruby
I cannot read this, and ruby cannot read it bit by bit.

Page: 24

QUIC - reading Initial Packet by Ruby
How to read each "bit" in Ruby?
"A" ← 0x41 (ASCII-8BIT)
"A" ← 0b01000001 (ASCII-8BIT)
"A" → ? → "01000001"

Page: 25

QUIC - reading Initial Packet by Ruby
Use "Array#pack", "String#unpack1"
"A".unpack1("B*") # => "01000001"
["01000001"].pack("B*") # => "A"
Now, we can each "bit" by Ruby!

Page: 26

Handling packet by Ractor
How do we handling UDP packet by Ractor?

Page: 27

Handling packet by Ractor - think about QPACK
QPACK (Header Compression for HTTP/3)
Static Table
"content-encoding gzip" (values that appear many times)
Dynamic Table
per client-server
e.g. user-agent
→ Create ractor per client that has a dynamic table state...

Page: 28

Handling packet by Ractor - UDP echo server by Ractor
3 classes
Server class
Router class
Connection class

Page: 29

UDP echo server by Ractor - Server class

Page: 30

UDP echo server by Ractor - Router class

Page: 31

UDP echo server by Ractor - Connection class

Page: 32

benchmarking by udpbench
Improvised UDP benchmark tool written Go.
Send-receive UDP packet that contain UUIDv4 from goroutines.

Page: 33

Result of benchmark UDP echo server by Ractor
$ ./udpbench --count 100 --parallelism 100
Total request count : 10000
Total request time : 10m48.446641s
Time per packets : 64.844664ms
Failed count : 0

Page: 34

simple UDP echo server

Page: 35

Result of benchmark simple UDP echo server
$ ./udpbench --count 100 --parallelism 100
Total request count : 10000
Total request time : 7.5696799s
Time per packets : 756.967µs
Failed count : 0
x85 faster than Ractor impl

Page: 36

Let's decrypt QUIC packet in Ractor

Page: 37

Let's decrypt QUIC packet in Ractor
Failed by OpenSSL::Cipher.new
Can OpenSSL rb_ext_ractor_safe(true) ...?

Page: 38

Wait, I heard about yesterday...
'Standard libralies are already ractor-safe' by ko1
I heard about that in "Ruby Committers vs the World" yesterday.

Page: 39

OpenSSL is `rb_ext_ractor_safe(true)`

Page: 40

There are two problems
Libraies that cannot use in not main Ractor
useful gem → imprement myself (e.g. bindata)
core lib → DEEP DIVE to fix this (e.g. openssl)
Need many many code to imprement QUIC
Mozilla's Neqo : 50,000 LoC (Rust) https://github.com/mozilla/neqo
aioquic : 17,000 LoC (Python) https://github.com/aiortc/aioquic
Ruby : ?

Other slides

CNDF2023 CNDF2023
ruby30th-lt ruby30th-lt