В очередь, сукины дети!

24.04.2014 в 16:00 ruby gem queue workers

В одном из моих проектов понадобилась простая, быстрая и надёжная очередь сообщений. Сразу оговорюсь - проект не на Rails. Sinatra + PostgreSQL = API-сервер. Первое, что приходит в голову - Sidekiq и Resque. Ничего не могу про них сказать плохого или хорошего - никогда не использовал... и не планирую пока. Эти продукты мне не подходили. Нужно было что-то простое и понятное. Мне не хотелось поднимать дополнительные сущности вроде Redis'а, RabbitMQ и прочих. У меня уже был PostgreSQL - простой и надёжный как топор. И тут, впрочем как всегда, помог Google - я нашел его - простой провайдер и обработчик очереди сообщений с PostgreSQL в качестве бэкэнда.

Ставится все по старинке:

gem install queue_classic

... и добавляется в Gemfile проекта:

gem 'queue_classic'

Далее создайте таблицу для добавления сообщений в очередь:

bundle exec rake qc:create

Для worker'а пишется Rakefile:

ENV["QC_DATABASE_URL"] = "postgres://api:ipa@db_host/db_api"
    ENV["QC_PUSH_DEBUG"] = "true" 

    require 'bundler'

    Bundler.require

    require 'queue_classic'
    require 'queue_classic/tasks'

    class Worker

        def self.process_message hash
            if ENV["QC_PUSH_DEBUG"] == "true"
                puts "param1 = #{hash['param1']}"
                puts "param2 = #{hash['param2']}"
                puts "param3 = #{hash['param3']}"
            end
            # do something with message
        end

    end

Чтобы добавлять сообщения в очередь include'им в приложение класс QC:

module Helpers
        module Messages

            include QC
            
            def put_message_to_queue
                QC.enqueue('Worker.process_message', { 'param1' => 'param1', 'param2' => 'param2', 'param3' => 'param3' })
            end
        end
    end

Далее параллельно с приложением запускаем воркер или несколько воркеров:

bundle exec rake qc:work

Количество воркеров ограниченно ресурсами сервера и решаемой задачей.

Как-то так. Все предельно просто и надёжно. Главное решает свою задачу на "отлично".


Полезности:

#344 Queue Classic

Getting started with QueueClassic