Slide 1

Slide 1 text

Fiber Scheduler vs. General-Purpose Parallel Client
 2025.04.17

Slide 2

Slide 2 text

Premises and Issues


Slide 3

Slide 3 text

3 Underlying Architecture
 User
 Service
 Internal Service A
 Internal Service B
 Internal Service C


Slide 4

Slide 4 text

4 Problems to Be Solved
 User
 Service
 Internal Service A
 Internal Service B
 Internal Service C
 Latency


Slide 5

Slide 5 text

5 What We Want to Achieve (Parallel Requests)
 User
 Service
 Internal Service A
 Internal Service B
 Internal Service C
 Latency


Slide 6

Slide 6 text

6 Requirements for the Parallel Request Client
 ● It should be able to send parallel requests in a unified way across different HTTP client gems
 ○ For example: faraday gem, grpc gem, aws-sdk gem
 ● Should be easy for in-house engineers to understand and use


Slide 7

Slide 7 text

Approach


Slide 8

Slide 8 text

8 Parallel Requests Using the faraday-em_synchrony Adapter
 ● Initially, we wanted to address the issue of having many Faraday requests
 ● faraday-em_synchrony is one of Faraday’s adapters that allows parallel requests
 ○ This approach is currently running in the production environment
 ● Issues with this approach:
 ○ It depends on the EventMachine gem, which hasn't had a release since 2018 and is somewhat outdated
 ○ It only works with Faraday
 ○ It is not compatible with Faraday 2.x


Slide 9

Slide 9 text

9 Is Fiber Scheduler a Better Option?
 ● Fiber Scheduler is a mechanism that enables concurrent processing using Fibers
 
 ● Implementations like the async gem allow the scheduler to delegate execution to other Fibers when I/O blocking occurs, such as with IO#wait, IO#read, or IO#write in Ruby


Slide 10

Slide 10 text

With Fiber Scheduler, almost everything worked perfectly!!!


Slide 11

Slide 11 text

...Almost...? 😅


Slide 12

Slide 12 text

12 Recap of How Fiber Scheduler Works
 ● When a Fiber Scheduler is present, Ruby internally checks and delegates certain I/O operations to the scheduler
 ○ For example: in the implementation of IO#wait, there's logic to invoke the Fiber Scheduler if it exists


Slide 13

Slide 13 text

13 Async::Scheduler#io_wait
 Recap of How Fiber Scheduler Works
 ● When a Fiber Scheduler is present, Ruby internally checks and delegates certain I/O operations to the scheduler
 ○ For example: in the implementation of IO#wait, there's logic to invoke the Fiber Scheduler if it exists


Slide 14

Slide 14 text

14 So, What Kinds of Things Can Be Handled Concurrently with Fiber Scheduler?
 ● Methods like Ruby’s IO#wait, which have specific behavior defined when a Fiber Scheduler is present
 ○ cf. https://docs.ruby-lang.org/en/3.4/Fiber/Scheduler.html 
 
 ● Even methods implemented in native extensions, as long as they define behavior for when a Fiber Scheduler is available


Slide 15

Slide 15 text

15 ● It should be able to send parallel requests in a unified way across different HTTP client gems
 ○ For example: faraday gem, grpc gem, aws-sdk gem
 
 ● Should be easy for in-house engineers to understand and use
 Now, let's revisit and reorganize the requirements for the parallel request client.


Slide 16

Slide 16 text

16 ● It should be able to send parallel requests in a unified way across different HTTP client gems
 ○ For example: faraday gem, grpc gem, aws-sdk gem
 
 ● Should be easy for in-house engineers to understand and use
 Now, let's revisit and reorganize the requirements for the parallel request client.


Slide 17

Slide 17 text

17 What’s the Problem with the grpc Gem?
 gRPC Core
 gRPC Core
 Ruby Gem
 gRPC Core
 PHP Package
 gRPC Core
 Python Package


Slide 18

Slide 18 text

18 What’s the Problem with the grpc Gem?
 ● The logic for sending gRPC requests and waiting for responses is implemented in the C-based gRPC core


Slide 19

Slide 19 text

19 What’s the Problem with the grpc Gem?
 ● The logic for sending gRPC requests and waiting for responses is implemented in the C-based gRPC core
 This leaves no room to hook in Ruby’s Fiber Scheduler for concurrent handling!


Slide 20

Slide 20 text

Given this, let's abandon the Fiber Scheduler approach and switch to a Thread-based approach instead.


Slide 21

Slide 21 text

21 Can We Use Threads to Parallelize with the grpc Gem?
 
 


Slide 22

Slide 22 text

Conclusion


Slide 23

Slide 23 text

23 Conclusion
 ● I set out to build a general-purpose parallel request client
 ● Wanted to unify and parallelize various HTTP clients like Faraday, gRPC, and AWS SDK
 ● But it turned out that gRPC's implementation doesn't work well with Fiber Scheduler for parallelization
 ● So now, I'm building an easy-to-use parallel client using Threads that works smoothly with all of them!
 ○ To be continued...


Slide 24

Slide 24 text

  24 ● Co-Founder of Kyobashi.rb.
 ● Organizer of 関西Ruby会議08
 ● Organizer of Kaigi on Rails.
 ● Author of the book "Learning Electronics with Ruby"
 hachi
 Engineer at freee K.K.
 @hachiblog


Slide 25

Slide 25 text

  25 ● Co-Founder of Kyobashi.rb.
 ● Organizer of 関西Ruby会議08
 ● Organizer of Kaigi on Rails.
 ● Author of the book "Learning Electronics with Ruby"
 hachi
 Engineer at freee K.K.
 @hachiblog


Slide 26

Slide 26 text

  26 ● Co-Founder of Kyobashi.rb.
 ● Organizer of 関西Ruby会議08
 ● Organizer of Kaigi on Rails.
 ● Author of the book "Learning Electronics with Ruby"
 hachi
 Engineer at freee K.K.
 @hachiblog


Slide 27

Slide 27 text

  27 ● Co-Founder of Kyobashi.rb.
 ● Organizer of 関西Ruby会議08
 ● Organizer of Kaigi on Rails.
 ● Author of the book "Learning Electronics with Ruby"
 hachi
 Engineer at freee K.K.
 @hachiblog


Slide 28

Slide 28 text

  28 ● Co-Founder of Kyobashi.rb.
 ● Organizer of 関西Ruby会議08
 ● Organizer of Kaigi on Rails.
 ● Author of the book "Learning Electronics with Ruby"
 hachi
 Engineer at freee K.K.
 @hachiblog