Событийно-ориентированная архитектура — это парадигма, где поток выполнения программы определяется событиями (внешними или внутренними). В Ruby она особенно полезна для I/O-bound приложений.
# Простейший event loop
event_queue = Queue.new
# Генератор событий
Thread.new do
5.times do |i|
sleep rand(0.1..0.5)
event_queue << [:event, "Событие #{i}"]
end
event_queue << [:done, nil]
end
# Обработчик событий
loop do
type, payload = event_queue.pop
case type
when :event
puts "Обработка: #{payload}"
when :done
break
end
end
require 'eventmachine'
EM.run do
# Таймер - пример события
EM.add_timer(1) { puts "Таймер сработал" }
# Асинхронный HTTP-запрос
EM.defer do
response = Net::HTTP.get(URI("http://example.com"))
EM.schedule { puts "Получено: #{response.size} байт" }
end
EM.add_periodic_timer(2) { puts "Периодическое событие" }
end
module Observable
def initialize
@observers = []
end
def add_observer(&observer)
@observers << observer
end
def notify_observers(data)
@observers.each { |o| o.call(data) }
end
end
class Sensor
include Observable
def detect_change
# При изменении состояния
notify_observers(Time.now)
end
end
sensor = Sensor.new
sensor.add_observer { |time| puts "Обнаружено изменение в #{time}" }
require 'socket'
server = TCPServer.new('0.0.0.0', 3000)
sockets = [server]
loop do
ready = IO.select(sockets)
ready[0].each do |socket|
if socket == server
client = server.accept
sockets << client
puts "Новое подключение"
else
data = socket.gets
if data
socket.puts "Echo: #{data}"
else
socket.close
sockets.delete(socket)
end
end
end
end
require 'socket'
require 'fiber'
require 'fiber/scheduler'
Fiber.set_scheduler(Event.new)
Fiber.schedule do
server = TCPServer.new('0.0.0.0', 3000)
loop do
client = server.accept
Fiber.schedule do
while data = client.gets
client.puts "Echo: #{data}"
end
client.close
end
end
end
Преимущества:
Недостатки:
Резюмируем: Событийно-ориентированный подход в Ruby реализуется через EventMachine, Fibers, или чистые Threads с очередями. Для современных проектов стоит рассматривать Fiber Scheduler из Ruby 3+. Эта парадигма идеальна для сетевых и I/O-интенсивных приложений, но требует переосмысления традиционного линейного кода.