Computer >> Máy Tính >  >> Lập trình >> Ruby

Viết kịch bản một lần trong Rails

Bạn đã bao giờ muốn nhập một loạt dữ liệu vào ứng dụng của mình từ tệp CSV chưa? Hoặc có thể bạn cần sửa các ký tự được mã hóa sai trong một số bài đánh giá của khách hàng. Hoặc bạn đã thay đổi ý định về cách bạn muốn lưu trữ dữ liệu trong Redis và phải chuyển mọi thứ từ định dạng cũ sang định dạng mới.

Tại Avvo, chúng tôi gọi đây là “nhiệm vụ đặc biệt”. Như trong, bạn có thể chỉ cần chạy chúng một lần. Vậy cách tốt nhất để xử lý một nhiệm vụ đặc biệt trong Rails là gì?

Viết di chuyển cơ sở dữ liệu

Quá trình di chuyển hoạt động tốt nếu bạn cần thay đổi cấu trúc của dữ liệu trong cơ sở dữ liệu của mình. Nó theo dõi xem tác vụ đã được chạy hay chưa, nó mang theo những thay đổi đối với các môi trường khác - đó là những gì di chuyển được xây dựng vì. Đó cũng là những gì bạn có thể đã sử dụng chúng để làm.

Nếu bạn đang thay đổi dữ liệu cùng một lúc, việc di chuyển có thể làm việc tốt. Nhưng có một số điều cần chú ý.

Gọi một cái gì đó như Permissions.create(...) trong quá trình di chuyển của bạn có thể khiến bạn gặp rắc rối. Nếu mô hình đã thay đổi, quá trình di chuyển của bạn có thể bị hỏng vì mô hình của bạn có thể không khả dụng khi quá trình di chuyển chạy. Hoặc mô hình của bạn có thể đã thay đổi giữa thời điểm bạn viết quá trình di chuyển và khi nó chạy. Có nhiều cách để giải quyết vấn đề này, nhưng chúng dễ xảy ra lỗi và có thể thất bại theo những cách kỳ lạ.

Việc di chuyển cũng ít hữu ích hơn nếu nhiệm vụ của bạn không liên quan đến ActiveRecord.

Đây không phải là những kẻ phá vỡ thỏa thuận. Nhưng tôi có xu hướng không nhập hoặc thay đổi nhiều dữ liệu trong quá trình di chuyển. Có nhiều lựa chọn tốt hơn.

Viết nhiệm vụ cào

Bạn có một nhiệm vụ. Bạn có thể chỉ muốn chạy nó một lần. Và bạn muốn có thể kiểm tra nó trên máy của mình và chạy nó trong sản xuất.

Tác vụ cào hoạt động thực sự hiệu quả cho việc này. Rails thậm chí có thể tạo ra các tác vụ cào cho bạn:

$ be rails g task locations import
      create  lib/tasks/locations.rake

Thao tác này tạo một tệp để bạn lưu trữ mã của mình vào:

lib / task / locations.rake
namespace :locations do
  desc "TODO"
  task import: :environment do

  end
end

Bên trong task đó chặn, bạn có thể sử dụng tất cả các mô hình của mình và phần còn lại của mã trong ứng dụng Rails của bạn. Dễ dàng nhập và thay đổi dữ liệu vì bạn có thể viết mã của mình giống như bạn đang ngồi trên bảng điều khiển Rails.

Khi bạn đã viết xong nhiệm vụ của mình, bạn có thể chạy nó với rake locations:import . Nếu bạn đang sử dụng Heroku, bạn có thể chạy nó với heroku run rake locations:import . Nếu đang sử dụng Capistrano, bạn có thể sử dụng đá quý capistrano-rake để thực hiện nhiệm vụ của mình. Tuy nhiên, bạn có thể có một lựa chọn tốt hơn.

Viết một công việc đã lên lịch, sử dụng sidekiq-Scheduler

Nếu ứng dụng của bạn đủ lớn, bạn có thể là đã sử dụng Sidekiq, Resque hoặc những thứ tương tự.

Hầu hết các bộ xử lý công việc nền này có thể lên lịch công việc để chạy sau. Ví dụ:trong Sidekiq, có viên ngọc trình lập lịch trình sidekiq. Và với sidekiq-Scheduler, bạn có thể thực hiện một mẹo nhỏ.

Điều gì sẽ xảy ra nếu bạn có một công việc không bao giờ tự động tự lên lịch, nhưng hãy để bạn theo cách thủ công lên lịch bất cứ khi nào bạn muốn? Điều đó sẽ hiệu quả đối với những công việc “một lần” mà bạn có thể muốn chạy lại sau này hoặc bạn muốn chạy bằng giao diện người dùng.

Trong trình lập lịch trình sidekiq, bạn có thể lên lịch công việc trong tương lai xa và đặt công việc thành vô hiệu hóa:

sidekiq.yml
:schedule:
  location_importer:
    class: LocationImporterWorker
    at: '3001/01/01'
    enabled: false

Sau đó, khi bạn truy cập sidekiq-web, bạn sẽ thấy một nút để sắp xếp công việc theo cách thủ công:

Viết kịch bản một lần trong Rails

Với điều này, bạn có thể thực hiện công việc của mình bất cứ khi nào bạn sẵn sàng, trong cả quá trình phát triển và sản xuất. Và nếu bạn cần chạy lại, nó sẽ có ngay trong giao diện người dùng.

Đây không phải là lựa chọn tốt nhất nếu công việc của bạn nguy hiểm. Quá dễ dàng nếu vô tình nhấp vào nút đó. Và cũng không tuyệt vời nếu công việc mất một lúc để hoàn thành, bởi vì Sidekiq hoạt động tốt nhất nếu công việc kết thúc nhanh chóng. Công việc của bạn sẽ tiếp quản một nhân viên và bạn sẽ không thể khởi động lại Sidekiq một cách an toàn cho đến khi công việc của bạn kết thúc. Nhưng nếu công việc của bạn diễn ra nhanh chóng và có thể chạy an toàn nhiều lần, thì điều này sẽ hoạt động tốt. Nếu đó là một loại nhiệm vụ dọn dẹp, bạn có thể quyết định bạn muốn để chạy nó thường xuyên.

Nếu bạn chỉ muốn tập trung vào việc lập lịch và kích hoạt, hoặc cần linh hoạt hơn để thiết lập các tham số trong các tập lệnh một lần của mình, một độc giả, Dmitry, đã chỉ cho tôi về sidekiq-enqueuer. Với sidekiq-enqueuer, bạn có thể lên lịch công việc và đặt thông số, tất cả đều thông qua giao diện web Sidekiq.

SSH vào sản xuất và dán mã vào bảng điều khiển Rails

Đùa thôi.

Bạn nên chọn cái nào?

Tôi đã sử dụng tất cả những cách này để chạy các tác vụ một lần. Nhưng tôi thường sẽ thực hiện nhiệm vụ cào trước. Nó hoạt động, rất khó để vô tình chạy và rất dễ bị loại bỏ khi bạn làm xong. Tuy nhiên, tôi không chọn nhiệm vụ cào mọi lúc.

Tôi có thể chọn di chuyển nếu:

  • Công việc sửa dữ liệu bằng cách sử dụng SQL như một phần của thay đổi giản đồ cơ sở dữ liệu.
  • Công việc là công việc dữ liệu rất đơn giản, chẳng hạn như thay đổi dữ liệu trong một cột hoặc thêm một vài bản ghi.
  • Tôi muốn dễ dàng theo dõi xem công việc đã được chạy hay chưa và không chạy lại.

Tôi có thể chọn một công việc Sidekiq nếu:

  • Tôi nghĩ tôi có thể muốn chạy lại công việc sau.
  • Ai đó không phải là tôi phải điều hành nó. Tất cả những gì họ phải làm là nhấp vào một nút.
  • Đây là công việc nhập dữ liệu ngắn hoặc công việc dọn dẹp dữ liệu. Có lẽ tôi sẽ phải chạy những cái đó thường xuyên, ngay cả khi ban đầu tôi không mong đợi.

Còn bạn thì sao? Bạn có bất kỳ lựa chọn nào khác hoặc đưa ra các lựa chọn khác nhau không? Để lại nhận xét và cho tôi biết!