有什么类似于delayed_job,但没有工人?

时间:2011-10-07 08:38:25

标签: ruby-on-rails-3 delayed-job

在我的应用中,当用户注册时,会向他们发送确认电子邮件。我使用delayed_job,让发送邮件的过程在后台进行。

但使用delayed_job的缺点是一直有工人。有一个工人为此是昂贵的。

除了delayed_job之外还有什么东西可以让电子邮件发送到后台。

这是我的控制器代码段。

def create
    @user = User.new(params[:user])

    respond_to do |format|
      if @user.save
        UserMailer.delay.registration_confirmation(@user)
        format.html { redirect_to @user, notice: 'User was successfully created.' }
        format.js

重点是我一天有20-40个注册。这意味着队列最多忙了大约60秒,我将不得不支付整天的费用,这是非常不切实际的。其他一些不错的方法。

2 个答案:

答案 0 :(得分:0)

我建议设置一个每小时运行一次的cron并发送电子邮件。您必须创建新模型QueuedEmail或类似的模型,然后立即将其另存为QueuedEmail,而不是立即使用ActionMailer。这与delayed_job基本相同,但是你可以更好地控制它何时运行,而且crons不会占用太多内存。

cron应该是脚本/ rails runner,你应该在QueuedEmail模型中有一个方法发送所有待处理的电子邮件。我建议whenever生成crontabs(快速设置并且非常易于使用)。 cron看起来像这样(这个例子设置为每天凌晨2点运行一次,你可以查看如何调整间隔,我不知道在我的头顶):

0 2 * * * /bin/bash -l -c 'cd /RAILS_ROOT/ && script/rails runner -e production '\''QueuedEmail.send_pending'\'' >> log/cron.log 2>&1'

或者每当:

every :day, :at => '2 am' do
    runner "QueuedEmail.send_pending"
end

<强> QueuedEmail#send_pending

class QueuedEmail < ActiveRecord::Base
    def send_pending
        all.each do |email|
            params = your_parsing_method(email.params)
            record = your_parsing_method(email.record)
            email.destroy if UserMailer.registration_confirmation(record, params).deliver
        end
    end
end

<强> UserController的#创建

if @user = User.create(params[:user])
    User.delay_email(@user, params[:user])
    redirect_to user_path(@user), :notice => "Created User. E-mail will be sent within the hour."
end

用户#delay_email

def delay_email(record, params)
    QueuedEmail.create(:record => your_db_formatting_method(record), :params => your_db_formatting_method(params.to_s)) # or use something built in, like to_s.
end

这些代码都没有经过测试,可能已经完全被破坏了,但重要的是这一点。您还可以更进一步扩展Rails ActionMailer,但这要先进得多。

答案 1 :(得分:0)

如果您仅使用作业发送“注册邮件”,那么最好不要使用单独的作业(考虑到您发送的电子邮件数量非常少)。

这将简化您的配置并降低您的成本。

如果您的任务需要花费大量时间才能完成,或者您的网站非常繁忙,那么分离的作业非常有用,因为它不是这两种情况,只是发送常规电子邮件是个好主意。