Gem позволяет быстро и достаточно просто организовать многопоточную обрабтку ввода-вывода. Имеет свой внутренний пул подключений.
Достаточно принести сам gem:
gem install eventmachine
В своём проекте я применял его в двух ипостасях - для отслеживания изменений в директориях и для работы с tcp сокетом.
Принцип следующий - создаётся класс-потомок EventMachine::Connection, в котором переопределяются нужные методы. Выбор достаточно большой, я использовал два
А вот и пример кода
require 'json' require 'eventmachine' module OwlStore class Server < EventMachine::Connection def post_init puts "Recieved a new connection" end def receive_data(data) data.chomp! puts "Recieved data is '#{data}'" begin data = JSON.parse(data) send_data(JSON.generate({statue:'ok'})) rescue => e send_data(JSON.generate({error:"Malformed JSON data: #{e}"})) end close_connection_after_writing end end end EventMachine.run { EventMachine.start_server '127.0.0.1', 8800, OwlStore::Server }
Иногда возникает желание отслеживать что происходит в директории или непосредственно с файлами, чтобы соответствующим образом обрабатывать события. Можно конечно держать свой собственный цикл, который будет постоянно дёргать содеримое файла/директории, а можно завязаться на замечательную способность ОС Linux - inotify. Всю обвязку уже сделали за нас, нам остаётся только сесть и поехать.
Как и с tcp сервером мы создаём класс потомок, только на этот раз унаследованный от EventMachine::FileWatch. Кстати во все классы потомки можно передавать свои собственные аргументы, что может упростить впослежствии разработку. (Например можно отказаться от глобальной переменной конфигурации и передавать в объект только нужные части) В своём классе потомке я переопределил опять же два метода, но на этот раз это стал конструктор и
Попутно доступны
И сразу же пример1)
require "eventmachine" module OwlServer class Queue < EventMachine::FileWatch def initialize(config) puts "INotify watcher configured with #{config}" @config = config end def file_modified puts "#{path} modified" end def file_moved puts "#{path} moved" end def file_deleted puts "#{path} deleted" end def unbind puts "#{path} monitoring ceased" end end end Dir.mkdir("/tmp/uploads/") unless Dir.exists? ("/tmp/uploads/") EventMachine.run { EventMachine.watch_file("/tmp/uploads/", OwlServer::Queue, {config: 'true'}) }