-
-
Notifications
You must be signed in to change notification settings - Fork 6
Basic Usage
LightIO is all about Concurrency and IO.
Use LightIO::Beam to write concurrency code.
result = []
b1 = LightIO::Beam.new {result << 1}
b2 = LightIO::Beam.new {result << 2}
b1.join
b2.join
puts result # 1, 2
puts b1.alive?, b2.alive? # false, false
Beam is a cheaper version thread, use it do the "one thread per client" job, you can gain better concurrency performance.
# echo server example, use telnet to test
LightIO::TCPServer.open('127.0.0.1', 3000) do |server|
puts "start echo server"
while (socket = server.accept)
LightIO::Beam.new(socket){|s|
_, port, host = s.peeraddr
puts "accept connection from #{host}:#{port}"
loop {s << s.readpartial(4096) rescue break puts("client leave #{host}:#{port}")}
}
end
end
Cause beam is not a "real" thread, it will blocking all beams if you do a system IO blocking operation.
LightIO provide IO related classes/modules under LightIO namespace, those modules implemented the same stdlib API(some of them just wrap the stdlib class), use those modules can trigger Beam control-flow transfer, you must use those libraries to instead stdlib to avoid whole beams blocking.
# example: use LightIO::Queue to pass messages between beams
q = LightIO::Queue.new
b1 = LightIO::Beam.new {q.pop}
b2 = LightIO::Beam.new {q << "it will blocking forever if use ::Queue"}
b1.join
b2.join
puts b1.value, b2.value
# it will blocking forever if use ::Queue
# <LightIO::Library::Queue:0x007f818387ef18>
Cause LightIO use nio4r to provide IO loop, and nio4r support multi backends, LightIO allow user use env variable to choose one.
export LIGHTIO_BACKEND=epoll
# print current backend
puts "available: #{NIO::Selector.backends}"
puts "using: #{LightIO::IOloop.current.backend}"