Мне действительно не нравятся такие гемы, как delayed_job
и background_job
, которые сохраняются в базе данных для выполнения асинхронных заданий. Это просто кажется мне грязным. Временный материал не принадлежит базе данных.
Я большой поклонник очередей сообщений для решения асинхронных задач, даже если вам не нужна огромная масштабируемость. На мой взгляд, очереди сообщений являются идеальным языком общения для сложных систем. С помощью очереди сообщений в большинстве случаев у вас нет ограничений на технологии или языки, которые задействованы во всем, что вы создаете. Преимущества использования очереди сообщений с низким уровнем параллелизма, вероятно, наиболее заметны в «корпоративной» среде, где интеграция всегда сопряжена с большими трудностями. Кроме того, очереди сообщений идеальны, когда ваш асинхронный рабочий процесс включает в себя несколько шагов. RabbitMQ - мой личный фаворит.
Например, рассмотрим сценарий, в котором вы создаете поисковую систему. Люди могут отправлять URI для индексации. Очевидно, что вы не хотите получать и индексировать страницу в запросе. Итак, вы строите вокруг очереди сообщений: цель отправки формы берет URI, выбрасывает его в очередь сообщений для индексации. Следующий доступный процесс-паук извлекает URI из очереди, извлекает страницу, находит все ссылки, помещает каждую из них обратно в очередь, если они неизвестны, и кэширует содержимое. Наконец, новое сообщение помещается во вторую очередь для процесса индексатора для обработки кэшированного содержимого. Процесс индексатора извлекает это сообщение из очереди и индексирует кэшированное содержимое. Конечно, слишком упрощенно - в поисковых системах много работы, но вы поняли.
Что касается настоящих демонов, то, очевидно, я неравнодушен к своей собственной библиотеке (ChainGang), но на самом деле это всего лишь обертка вокруг Kernel.fork (), которая дает вам удобное место для работы с кодом установки и демонтажа. Это также еще не совсем сделано. На самом деле часть демона гораздо менее важна, чем очередь сообщений.
Что касается среды Rails, то, пожалуй, лучше всего оставить это упражнение для читателя, поскольку использование памяти будет существенным фактором по сравнению с длительным процессом. Вы не хотите загружать то, что вам не нужно. Между прочим, это одна из областей, в которой DataMapper разумно пинает задницу ActiveRecord. Инициализация среды хорошо документирована, и в игру вступает гораздо меньше зависимостей, что делает весь набор и кабул значительно более реалистичным.
Единственное, что мне не нравится в cron + rake, это то, что rake практически гарантированно печатает на стандартный вывод, а cron имеет тенденцию быть слишком болтливым, если ваши задания cron выдают результат. Мне нравится помещать все мои задачи cron в каталог с соответствующим именем, а затем создавать rake-задачу, которая оборачивает их, так что запускать их вручную вручную тривиально. Обидно, что рейк делает это, потому что я действительно предпочел бы иметь возможность воспользоваться зависимостями. В любом случае, вы просто указываете cron непосредственно на сценарии, а не запускаете их через cron.
В настоящее время я занимаюсь созданием веб-приложения, которое в значительной степени опирается на асинхронные процессы, и я должен сказать, что я очень, очень рад, что решил не использовать Rails.