Ở bài trước mình có chia sẻ về Crontab trong Linux. Khi đó chúng ta sẽ thao tác trực tiếp với file Crontab thông qua lệnh crontab -e
. Nhưng nếu trong Rails project của mình có yêu cầu phải lên lịch task chạy ngầm thì phải làm sao? Không lẽ copy nguyên câu lệnh chạy task của Rails vào Crontab ư?
Đúng! Bản chất vẫn sẽ là ghi câu lệnh thực thi task của Rails vào Crontab, nhưng sẽ có gem làm thay ta việc đó, ta chỉ việc ra lệnh cho gem đó thôi, bằng thứ ngôn ngữ dễ hiểu hơn 5 dấu sao của Crontab nhiều!
Gem Whenever
Cài đặt
(GitHub: https://github.com/javan/whenever)
# Gemfile
gem 'whenever', :require => false
$ bundle
$ cd /apps/my-great-project
$ wheneverize .
Lệnh $ wheneverize .
sẽ tạo file config/schedule.rb
trong project, đây chính là nơi để ta lên lịch cho các task.
Sau đó ta có thể dùng các lệnh sau, cũng chính là những lệnh sẽ dùng thường xuyên khi làm việc với Whenever:
whenever
: Hiển thị danh sách các task đã được lên lịch, tương tự vớicrontab -l
whenever -i
: Cập nhật file Crontab. Mỗi khi chúng ta chỉnh sửa fileconfig/schedule.rb
, chạy lệnh này sẽ cập nhật những thay đổi đó vào file Crontab của hệ thống.whenever -c
: Xóa tất cả task đã được lên lịch, tương tự vớicrontab -r
whenever -h
: Xem hướng dẫn tất cả các lệnh có thể dùng.
Sử dụng
Chúng ta hãy cùng xem ví dụ sau:
# schedule.rb
every '1 * * * * ' do
rake 'update_expired_product'
end
every 1.day, :at => '2:30 am' do
rake 'send_report_email_to_admin'
end
Như bạn thấy, ta có thể dùng song song 2 loại "ngôn ngữ" mà Whenever vẫn hiểu: ngôn ngữ crontab và ngôn ngữ tự nhiên. Với ngôn ngữ tự nhiên, có lẽ bạn đã hiểu phải viết nó thế nào khi lướt qua rồi :D
Khi cập nhật file schedule.rb
xong, ta chỉ cần chạy whenever -i
là gem sẽ dịch và cập nhật lại nội dung vào file crontab của hệ thống. Rất tiện.
Lưu ý
Vậy nếu có nhiều project cùng chạy trên một hệ thống, lại cùng dùng chung user thì sao? Chẳng lẽ mỗi khi update crontab ở mỗi project thì nó sẽ ghi đè lên nhau?
Rất may Whenever cung cấp cho ta một tùy chọn:
whenever --update-crontab
Khi chạy lệnh này ở mỗi project, trong file crontab thật sẽ có từng khu vực riêng dành cho từng project, chạy những task của riêng nó, không ảnh hưởng đến project khác. Ví dụ:
# Begin Whenever generated tasks for: home/ahihi/a_project/config/schedule.rb
#
# Some tasks for Project A...
#
# End Whenever generated tasks for: home/ahihi/a_project/config/schedule.rb
# Begin Whenever generated tasks for: home/ahihi/b_project/config/schedule.rb
#
# Some tasks for Project B...
#
# End Whenever generated tasks for: home/ahihi/b_project/config/schedule.rb
Bạn thậm chí còn có thể đặt "nick name" cho project:
whenever --update-crontab project_name
Chỉ cần thay project_name
bằng một "nick name" mà bạn tự đặt cho project để phân biệt với các project khác.
Happy scheduling!