This content originally appeared on DEV Community and was authored by hungle00
Ruby 3 comes with a lot of support tools for concurrency programming, one of them is Fiber Scheduler.
What is Fiber
Fiber can be seen as a lightweight thread or thread implemented at the programming language level instead of the OS level.
fiber = Fiber.new do
#...
end
fiber.resume # transfer / Fiber.schedule
A Fiber is a lightweight unit of execution that can be suspended and resumed at specific points. After a fiber is suspended, it can be resumed later at the same point with the same execution state. Fibers are often referred to as a mechanism for cooperative concurrency, but before Ruby 3, Fibers lacked the scheduler implementation to be useful.
Fiber scheduler
Since Ruby 3, Fibers have been given superpowers in the form of the FiberScheduler.
The Fiber Scheduler consists of two parts:
- Fiber Scheduler interface
- Fiber Scheduler implementation
What Ruby 3 implements is the interface. It would not use the scheduler unless a scheduler implementation is included.
If you want to enable the asynchronous behavior in Ruby, you need to set a Fiber Scheduler object
Fiber.set_scheduler(scheduler)
The list of Fiber Scheduler implementations and their main differences can be found at Fiber Scheduler List project.
I recommend you read this article to understand more detail about Fiber Scheduler.
Async gem:
One of the most mature and common Fiber Scheduler implementations is by Samuel Williams. Furthermore, he not only implemented a Fiber Scheduler but created the gem called Async which was more powerful for working with asynchronous programming.
If you want to go to details about the Async gem and how to use it, you should read the document Async Guides
The simple use of async gem is quite straightforward, you just need to wrap the computation code in Kernel#Async
method, for example:
require 'async'
Async do |task|
puts "Hello World!"
end
Simple asynchronous HTTP server
In this part, I'll implement the simple HTTP server using Async gem.
For simplicity, I will get the code from Appsignal's article Building a 30 line HTTP server in Ruby. After that, add the async gem to make the code asynchronous.
Using Fiber syntax + Async::Scheduler
require 'socket'
require 'async/scheduler'
Fiber.set_scheduler(Async::Scheduler.new)
server = TCPServer.new 2000 # Server bound to port 2000
app = Proc.new do
['200', {'Content-Type' => 'text/html'}, ["Hello world! The time is #{Time.now}"]]
end
Fiber.schedule do
loop do
session = server.accept # Wait for a client to connect
Fiber.schedule do
status, headers, body = app.call({})
session.print "HTTP/1.1 #{status}\r\n"
headers.each do |key, value|
session.print "#{key}: #{value}\r\n"
end
session.print "\r\n"
body.each do |part|
session.print part
end
session.close
end
end
end
or using Kernel#Async
method
require 'socket'
require 'async'
server = TCPServer.new 2000
app = Proc.new do
['200', {'Content-Type' => 'text/html'}, ["Hello world! The time is #{Time.now}"]]
end
Async do
loop do
session = server.accept # Wait for a client to connect
Async do
status, headers, body = app.call({})
# ... same code as above
end
end
end
This content originally appeared on DEV Community and was authored by hungle00
hungle00 | Sciencx (2024-10-23T14:53:14+00:00) Ruby Fiber Scheduler and Async. Retrieved from https://www.scien.cx/2024/10/23/ruby-fiber-scheduler-and-async/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.