2012-11-19 4 views
0

Итак, у меня многолетний процесс Ruby, который выполняет самые разные функции, в зависимости от того, что ему было сказано (EventMachine TCP-сервер с двоичными сообщениями). Теперь я хотел бы дать определенным людям возможность контролировать, изменять, закрывать данный процесс через веб-интерфейс. Я планирую использовать для этого Sinatra.rb, однако я открыт для лучших альтернатив.Практика для управления приложением Ruby «снаружи»

Моя первоначальная идея состояла в том, чтобы запустить веб-интерфейс Sinatra (он основан на Rack, для тех, кто не знаком с Sinatra) внутри Thread и позволяет ему работать в фоновом режиме.

Однако, я думал, что это может повлиять на производительность, если я делаю это именно так, поэтому я решил посмотреть в IPC способности и альтернативные реализации для Ruby (resque, совместного использования памяти, named pipes и т.д.).

Мне очень понравилась идея resque (и имя действительно остроумно), но я не совсем уверен, что это то, что мне нужно, или если это может быть излишним. На самом деле, я даже не уверен, как наилучшим образом реализовать его с помощью Sinatra и EventMachine (хотя я не прочитал полную документацию для resque, просто просмотрел ее быстро и прочитал примеры и примеры использования.).

Другая идея, которая пришла на ум, - использовать Sinatra внутри EventMachine::defer, но разве это не то же самое, что создавать новый Thread?

Я никогда не делал ничего серьезного, используя Fiber s, поэтому я не знаю их полностью потенциал, но они действительно пересекли мой разум.

Итак, какая из этих (или предложить лучше) практика является лучшей для Ruby PCI.

Благодаря

+0

Это очень много вопросов в одном. Постарайся быть более конкретным и, возможно, сделать несколько прототипов. Большинство упомянутых методов не так уж сложно настроить. –

+0

@BenjaminUdinktenCate Я знаю, но я думал, что попрошу кого-то более опытного (или у кого есть аналогичная проблема) предложить лучшую технику. – omninonsense

ответ

2

Я хотел бы предложить вам использовать сигналы для связи с вашим запущенным процессом.

При таком подходе это не имеет значения, какой каркас вы используете,
, хотя моя лучшая рекомендация Espresso Framework.

Так вот сделка. Есть много сигналов, которые вы можете отправить в свой процесс через интерфейс kill.

Сигналы могут быть отправлены из командной строки из другого процесса Ruby.

Все, что вам нужно - это поймать/отследить сигналы (ы) внутри вашего приложения.

Пример: в контролируемый процесс:

# build your app 

Signal.trap("USR1") do 
    # do some stuff here 
end 

Signal.trap("USR2") do 
    # do another stuff here 
end 

# run your app 

При запуске приложение убедитесь, чтобы получить его PID.

Имея PID вы можете посылать сигналы в ваше приложение через kill
(нет, он не будет убивать ваше приложение, если вы не отправить явный сигнал для этого).

Затем из другого процесса Ruby, вы можете сделать:

Process.kill "USR1", PID 

Или непосредственно из командной строки:

kill USR2 PID 

И ваше приложение будет ловить/ловушка посылает сигнал и сделать соответствующий материал.

Просто убедитесь, что заменили PID с реальным идентификатором процесса управляемого приложения.

Эта практика успешно используется веб-сервером Unicorn.

Вот список сигналов:

http://en.wikipedia.org/wiki/Unix_signal

некоторое представление о работе с сигналами в Ruby:

https://jellyjelly.net/blog/2010/04/27/unix-signal-programming-in-ruby/

0

Вы можете использовать локальную очередь сообщений, таких как RabbitMQ (реализация AMQP), но это фактически то же самое, что и использование Redis, как вы упомянули.

Такой подход не будет зависеть от конкретных механизмов взаимодействия между конкретными операционными системами. Так что да, у вас будет другая служба, но вы не будете связаны ни с чем на низком уровне. Это может быть очень хорошо, когда приходит время для масштабирования.