Как осуществляется программирование на основе событий? - PullRequest
2 голосов
/ 06 октября 2010

У меня довольно простой вопрос: как на самом деле достигается программирование на основе событий?

Чтобы уточнить: у меня есть приложение Rails, каждый раз, когда пользователь вносит изменения на веб-сайте, модель пишет, что «изменение«к текстовому файлу (как JSON.)

Я бы хотел подключить бот IRC к этому« событию ».(создание / модификация текстового файла.)

Как это вообще делается?Кажется, что это будет в основном бесконечный цикл.В псевдокоде:

while (I'm Listening)
do
  if (output.txt Is changed)
    process("output.txt")

Если это то, как достигается программирование на основе событий - как избежать блокировки процессора?Как бесконечные циклы имеют тенденцию делать?

Edit- IRC-сервер / бот размещаются на локально поддерживаемом блоке.Приложение Rails размещается на общем сервере.На данный момент я знаю, что мой IRC-бот может общаться с приложением Rails только через HTTP-запрос к серверу (или что-то подобное). Как я уже сказал, этот вопрос действительно более общий, как мне хотелось бычтобы получить знания о программировании, управляемом событиями в целом.

Я извиняюсь, если этот вопрос невероятно прост, но мое понимание программирования, управляемого событиями, состоит в том, чтобы присоединить предварительно созданные обработчики событий к объектам с помощью jQuery;который действительно не помогает при подключении бота IRC [написанного на Ruby] к файлу ввода / вывода.

Спасибо, Робби

Ответы [ 5 ]

4 голосов
/ 06 октября 2010

Чаще всего это так:

while (I'm Waiting to be notified) 
do 
  if (output.txt Is changed) 
    process("output.txt") 

В ОС (любой ОС) есть способы ожидания уведомления, не затрачивая процессорное время (например, переменная условия). Никакой управляемый событиями цикл не вращается в ожидании события.

2 голосов
/ 06 октября 2010

Я не уверен в чёрной магии, стоящей за ней, но популярный Ruby gem EventMachine имеет метод watch_file , который, похоже, подходит именно для вашего случая использования.Не нужно выполнять всю тяжелую работу самостоятельно, когда кто-то уже сделал это для вас.

Делитесь и наслаждайтесь.

РЕДАКТИРОВАТЬ: ваш комментарий к ответу Дейва Симса, кажется, подразумевает, что ваше приложение Railsи IRC-бот живет в разных файловых системах, и что файл JSON обслуживается по HTTP.Если это так, то вы все равно ожидаете HTTP-запросов и, следовательно, отправка HTTP-запроса как можно чаще (хотя я бы рекомендовал сделать несколько небольших пауз, чтобы избежать нарушения работы вашего сервера), не должна блокировать ЦП, посколькуон будет приостановлен во время ожидания ответа от сервера.Если в то же время бот-скрипту необходимо выполнять другие действия, то для этого нужно позаботиться о EventMachine и использовать гем em-http для отправки HTTP-запросов на основе событий.

Я до сих пор не совсем понимаю, что именно вы делаете.

2 голосов
/ 06 октября 2010

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

class Foo
  attr_accessor :event  #obviously not the right way to do it, but it will suffice

  def initialize
    @event = []
  end

  private
  def fire_event
    @event.each { |sub| sub.call }
  end
end

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

f = Foo.new
f.event << lambda { puts 'event was fired' }

Когда класс Foo вызывает метод fire_event, будет выполняться каждая процедура в наборе процедур. Нет петли, постоянно проверяющей какое-либо состояние. Когда возникает условие, вызывается метод стрельбы и выполняются процедуры.

Обратите внимание, что приведенный выше пример - это просто; пример. Реальная архитектура событий будет более надежной, но будет похожей. Это может даже не относиться к вашей реальной ситуации, но я не веб-парень, и я не знаю RoR и JSON и всех других причудливых ключевых слов, поэтому я поднялся на высокий уровень. Надеюсь, это поможет.

1 голос
/ 06 октября 2010

Возможно, вам следует создать DRb-сервер или использовать решение, которое использует это, например delayed_job. Вы можете запустить рабочих на разных машинах. Подключение осуществляется путем подключения к специальному порту на вашем сервере. Все, что вам нужно сделать, это открыть этот порт в брандмауэре для выделенной машины, на которой работает бот IRC. Вы можете поместить объекты ruby ​​в очередь, поэтому каждое изменение в файле может быть отражено путем помещения объекта ruby ​​в очередь, которая также содержит это изменение. Рабочий схватит это через несколько секунд, это не будет мгновенным. Но он все еще довольно быстрый, использует низкий процессор и способен справляться с перебоями в работе сети.

1 голос
/ 06 октября 2010

Обычно описываемый вами цикл while / listener создается в потоке, например, на сервере UDP или TCP, ожидающем соединения. Но это на самом деле не относится к вашей проблеме. Rails и ActiveRecord определяют ряд встроенных хуков в стиле Observer в моделях ActiveRecord, которые могут быть вам полезны. Смотрите здесь: http://api.rubyonrails.org/classes/ActiveRecord/Observer.html

Если вам действительно необходимо отслеживать состояние внешнего файла и обратные вызовы в стиле ActiveRecord или ActiveRecord не работают для вас, вы можете отслеживать файл с помощью упрощенного процесса-демона Ruby, который управляет блокировкой цикла while. Но я все еще не уверен, почему бы вам просто не использовать код Rails, который изменяет файл, чтобы также уведомлять вашего бота / процесс IRC и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...