0

Tự động gửi mail bằng Delayed_job

1. Giới thiệu

Delayed_job nhằm tạo ra các tiến trình không đồng bộ, giúp tạo ra các job xử lý tác vụ riêng biệt (gửi mail, ảnh, ...), có thời gian thực thi không đồng bộ với server, từ đó nhằm giảm tải và tăng hiệu suất thực thi cho server, mang lại hiệu quả cao.

Ở bài viết này, mình sẽ đề cập đến việc tự động gửi mail bằng cách sử dụng gem delayed_job, cụ thể hơn:

  • Khi user 1 login vào hệ thống, và tạo ra 1 bản ghi là store, bạn mong muốn rằng, 3 giờ sau sẽ có 1 mail tự động gửi đến cho user 2, thông báo răng user 1 đã tạo store trong hệ thống.
  • Thật ra, đây chỉ là một ví dụ để chúng ta dễ hình dung hơn về nội dung ở dưới đây và chức năng gửi mail tự động. Có một số trang web, Chatwork chẳng hạn, nó sẽ tự động gửi mail về thunderbird của chúng ta là có một thanh niên vừa chat với bạn, nhưng bạn vẫn chưa đọc message của thanh niên đấy (mail nhắc nhở).
  • Vậy đi vào phần tiếp theo về việc sử dụng delayed_job .

2. Cài đặt gem và tạo job

2.1 Cài đặt

gem 'delayed_job_active_record'

bundle, sau đó chạy lệnh

rails generate delayed_job:active_record
rake db:migrate

khác với sidekiq phải sử dụng môi trường redis-server hoặc cái gì đó tưong tự để lưu các thông tin cần thiết khi tạo job thì delayed_job sử dụng thông qua việc tạo 1 bảng để lưu các thông tin cần thiết phục vụ tác vụ.

trong file config/application.rb

config.active_job.queue_adapter = :delayed_job

Ok, bước cài đặt đã xong, việc tiếp theo là chúng ta tạo tác vụ như đã trình bày ở trên:

2.2 Tạo job

Việc đầu tiên trước khi tạo job, chúng ta cần tạo ra user_mailer để thực hiện gửi mail (gửi mặc định cho user_2):

def notify_create_store_email(store)
     @store = store
     subject = "notify_create_store_subject"
     mail(to: User.second, subject: subject)
   end
# notify_create_store_email.text.erb

Dear <%= User.second.name %>

<%= User.first.name %> have created <%= @store.name %> in website.
Have a nice day !

Vậy là xong phần user_mail, giờ đến phần chính là tạo job Chúng ta sẽ tạo một job với tên là "notify_create_store"

# app/jobs/notify_create_store_job.rb

class NotifyCreateStoreJob < ApplicationJob
  queue_as :notify_create_store

  def perform(store)
      UserMailer.notify_create_store_email(store).deliver
  end
end

job này đơn giản là khi tạo ra nó, nó sẽ gửi 1 cái mail với template mail như trên 😄

Việc chạy job này như thế nào:

Add gem:

gem "daemons"

bundle sau đó chạy lệnh tạo server quản lý các job

RAILS_ENV=... bin/delayed_job start

Mục tiêu quan trọng của bài này là:

  • Khi tạo store thì sau 3 tiếng sẽ gửi mail dùng call back after_create trong model store.rb
after_create :send_mail

def send_mail
    NotifyCreateStoreJob.set(wait: 3.hours).perform_later(self)
end

Nếu như muốn gửi mail ngay lập tức thì phải dùng

NotifyCreateStoreJob.new.perform(self)

3. Kết luận

Các tính năng gửi nhận mail, ảnh được sử dụng khá phổ biến trên các website hiện nay, và delayed_job có lẽ sẽ khá là hữu ích để thực hiện các chức năng này.

4. Tài liệu tham khảo

https://github.com/collectiveidea/delayed_job


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí