2010-11-08 40 views
19

Tôi có ứng dụng Rails 3 sử dụng Devise trên Heroku. Vấn đề là tôi đang gửi email với Sendgrid và gửi email chậm, nó làm cho ứng dụng bị treo. Vì vậy, tôi quan tâm đến việc sử dụng delay_job để xếp hàng gửi email trong nền để ứng dụng của tôi phản hồi người dùng.Rails + Devise + delay_job?

Làm thế nào để Devise có thể được sử dụng với delay_job? Bất kỳ cách nào để thiết lập Devise để sử dụng delay_job?

Trả lời

24

Từ Robert May: https://gist.github.com/659514

Thêm phần này vào một tập tin trong thư mục config/initializers:

module Devise 
    module Models 
    module Confirmable 
     handle_asynchronously :send_confirmation_instructions 
    end 

    module Recoverable 
     handle_asynchronously :send_reset_password_instructions 
    end 

    module Lockable 
     handle_asynchronously :send_unlock_instructions 
    end 
    end 
end 
+3

Thêm mã đó vào một số tệp.rb trong thư mục 'config/initializers'. – Zabba

+0

Điều này đã không làm việc cho tôi có lẽ do thực tế là phương pháp này không được hỗ trợ nếu sử dụng Rails 3 bưu phẩm mà ra có lẽ sử dụng. Xem liên kết này để biết thêm thông tin: https://github.com/collectiveidea/delayed_job và đi tới phần Rails 3 Mailers – sq1020

0

Không chắc chắn lý do tại sao bạn cần phải xác thực bất kỳ tác vụ bị chậm nào. Chỉ cần có các hành động điều khiển được xác thực Devise xếp hàng gửi email đến một phương thức thư viện.

1

Tôi không chắc chắn Devise cung cấp một cách dễ dàng để làm nền cho việc gửi email. Tuy nhiên có nhiều cách để có thể làm điều đó với DelayedJoy. DelyedJob cung cấp một hàm "handle_asynchronously" nếu được tiêm vào DeviseMailer có thể đảm bảo rằng việc giao hàng xảy ra trong nền.

Hãy thử điều này trong cấu hình của bạn/application.rb

config.after_initialize do 
    ::DeviseMailer.handle_asynchronously :deliver_confirmation_instructions 
    # or 
    ::DeviseMailer.handle_asynchronously :deliver! 
end 

Bạn sẽ cần phải thử nghiệm với điều đó. Bạn cũng có thể cố gắng kế thừa DeviseMailer và đặt nó để phân phối không đồng bộ trong bộ khởi tạo trong config/initializer/devise_mailer_setup.rb hoặc một cái gì đó để có hiệu lực đó.

-4

Tôi thường tìm thấy nó tốt nhất để tránh bất kỳ và tất cả các công việc quản lý tác vụ nền có sẵn cho Ruby và Rails, thời gian. Họ hút.

Thay vào đó, tôi sử dụng crontab là một chương trình cổ và rất giỏi trong công việc của mình. Chỉ cần thực hiện một kịch bản để làm công việc bẩn của bạn mỗi như vậy thường xuyên và nói với crontab để chạy nó vào đúng thời điểm bằng cách sử dụng đường ray Á hậu. Điều này giữ cho các tác vụ chạy lâu dài ngoài thời gian chạy của phần còn lại của ứng dụng Rails của bạn, nhưng bạn vẫn có quyền truy cập vào cơ sở dữ liệu và toàn bộ ngăn xếp Rails nếu bạn muốn/cần nó.

+5

Tôi không đồng ý với tuyên bố rằng "bất kỳ và tất cả người quản lý tác vụ nền" đều mút. Ruby Toolbox có một so sánh tốt đẹp về việc xếp hàng các tùy chọn cho Ruby: http://ruby-toolbox.com/categories/queueing.html –

+2

Vì vậy, hãy nói rằng bạn có một nhập khẩu đặt sản phẩm mới hoặc thông tin mới về sản phẩm vào ứng dụng của bạn. Bây giờ các sản phẩm mới cần tạo ra một số siêu dữ liệu hoặc những gì không. Bạn sẽ thêm một lá cờ vào bảng sản phẩm để cronjob của bạn có thể nhận những thứ đó? Bạn chạy cronjob bao lâu một lần? Cứ 10 phút một lần? Điều gì sẽ xảy ra nếu một lần thực thi chạy lâu hơn 10 phút. Bạn sẽ có các quy trình cạnh tranh đang chạy. Có vẻ như những gì bạn từng cố gắng để hack lên với crontab sẽ chỉ kết thúc là một người nghèo-mans-thực hiện một hàng đợi công việc. Tốt hơn là sử dụng hàng đợi chuyên dụng sẽ không làm hỏng lược đồ và mô hình cơ sở dữ liệu của bạn. –

0

Tôi sử dụng plugin delayed_job_mailer để thực hiện việc này trong ứng dụng Rails 2. Không chắc chắn nếu nó hoạt động với Rails 3.

6

tôi thấy rằng không có ở trên làm việc cho tôi. Tôi đang sử dụng Devise 2.0.4 và Rails 3.2.2 với delay_job_active_record 0.3.2

Cách thức thực sự nói về việc làm một cái gì đó như thế này trong các chú thích trong mã là ghi đè lên các phương thức trong lớp Người dùng. Vì vậy, tôi giải quyết nó như vậy, và nó hoạt động hoàn hảo:

app/models/User.rb

def send_on_create_confirmation_instructions 
    Devise::Mailer.delay.confirmation_instructions(self) 
end 
def send_reset_password_instructions 
    Devise::Mailer.delay.reset_password_instructions(self) 
end 
def send_unlock_instructions 
    Devise::Mailer.delay.unlock_instructions(self) 
end 
+0

over-riding những phương pháp này clobbers chức năng khác ... nó dường như làm việc, nhưng không đặt reset_password_token trên mô hình người dùng xem giải pháp của tôi – fringd

+2

Nếu bạn xem mã cho send_reset_password_instructions trong Devise mới nhất: # Đặt lại mã thông báo đặt lại mật khẩu và gửi hướng dẫn đặt lại mật khẩu qua email def send_reset_password_instructions generate_reset_password_token! if should_generate_reset_token? self.devise_mailer.reset_password_instructions (tự) .deliver kết thúc Đề xuất ở trên dẫn đến mã thông báo mật khẩu không được tạo. – justingordon

3

đây là điều mà làm việc cho tôi:

trong ứng dụng/mô hình/user rb

# after your devise declarations 
    handle_asynchronously :send_reset_password_instructions 
    handle_asynchronously :send_confirmation_instructions 
    handle_asynchronously :send_on_create_confirmation_instructions 

bạn có thể không cần tất cả trong số họ tùy thuộc vào đưa ra các module bạn đã bao gồm

+0

Làm việc cho tôi với Rails 3.2.16 và Devise 3.2.3. Tôi cũng đang sử dụng devise_invitable 1.3.4, mà tôi đã thêm 'handle_asynchronously: deliver_invitation'. –

+0

Vâng, tôi đã nhận xét quá sớm. Tôi cũng đã ghi đè 'send_reset_password_instructions' trong Mô hình người dùng của mình. Nó không hoạt động ngay khi chạy không đồng bộ. ZachBeta của [1/6/2014 bình luận về Github] (https://github.com/scambra/devise_invitable/issues/58) đã dẫn tôi thử 'handle_asynchronously: send_devise_notification' mà dường như xử lý mọi thứ kể cả lời mời. Mã nguồn Devise cũng có [nhận xét dài] (https://github.com/plataformatec/devise/blob/3d9dea39b2978e3168604ccda956fb6ec17c5e27/lib/devise/models/authenticatable.rb#L129-L174) về việc trì hoãn xếp hàng. –

+0

cách thực hiện điều này cho đá quý "devise_token_auth"? – vipin8169

0

Đối với delayed_job_active_record với Devise, chỉ cần sử dụng như sau. (thêm nó vào user.rb model)

handle_asynchronously :send_devise_notification, :queue => 'devise' 
Các vấn đề liên quan