Pertanyaan Praktik terbaik untuk Aplikasi Rails untuk menjalankan tugas yang panjang di latar belakang?


Saya memiliki aplikasi Rails yang sayangnya setelah permintaan ke controller, harus melakukan beberapa crunching yang membutuhkan waktu. Apa praktik terbaik dalam Rails untuk memberikan umpan balik atau kemajuan pada tugas atau permintaan yang berjalan lama? Metode pengontrol ini biasanya berlangsung 60+ detik.

Saya tidak peduli dengan sisi klien ... Saya berencana memiliki permintaan Ajax setiap detik atau lebih dan menampilkan indikator kemajuan. Saya tidak yakin dengan praktik terbaik Rails, apakah saya membuat pengontrol tambahan? Apakah ada sesuatu yang pintar yang bisa saya lakukan? Saya ingin jawaban fokus pada sisi server menggunakan Rails saja.

Terima kasih sebelumnya atas bantuan Anda.

Edit:

Jika penting, permintaan http adalah untuk PDF. Saya kemudian memiliki Rails bersama dengan Ruport menghasilkan PDF ini. Masalahnya, PDF ini sangat besar dan mengandung banyak data. Apakah masih masuk akal untuk menggunakan tugas latar belakang? Mari kita asumsikan PDF rata-rata membutuhkan waktu sekitar satu menit hingga dua menit, akankah ini membuat aplikasi Rails saya tidak responsif terhadap permintaan server lain selama waktu ini?

Edit 2:

Ok, setelah penyelidikan lebih lanjut, tampaknya aplikasi Rails saya memang tidak responsif terhadap permintaan HTTP lainnya setelah permintaan masuk untuk PDF besar. Jadi, saya kira pertanyaannya sekarang menjadi: Apa mekanisme threading / background terbaik untuk digunakan?  Itu harus stabil dan dipelihara. Saya sangat terkejut Rails tidak memiliki sesuatu seperti ini built in

Sunting 3:

Saya telah membaca halaman ini: http://wiki.rubyonrails.org/rails/pages/HowToRunBackgroundJobsInRails. Saya ingin sekali membaca tentang berbagai pengalaman dengan alat-alat ini.

Edit 4:

Saya menggunakan Passenger Phusion "modrails", jika itu penting.

Sunting 5:

Saya menggunakan Windows Vista 64 bit untuk mesin pengembangan saya; Namun, mesin produksi saya adalah Ubuntu 8.04 LTS. Haruskah saya mempertimbangkan beralih ke Linux untuk mesin pengembangan saya? Akankah solusi yang disajikan bekerja pada keduanya?


32


asal


Jawaban:


Itu Plugin workling memungkinkan Anda untuk menjadwalkan tugas latar belakang dalam antrian (mereka akan melakukan tugas yang panjang). Mulai versi 0.3, Anda dapat menanyakan statusnya kepada pekerja, ini akan memungkinkan Anda untuk menampilkan beberapa bilah kemajuan yang bagus.

Fitur keren lainnya dengan Workling adalah bahwa backend asynchronous dapat diubah: Anda dapat menggunakan DelayedJobs, Spawn (garpu klasik), Starling ...


24



Saya memiliki situs volume yang sangat besar yang menghasilkan banyak file CSV besar. Terkadang perlu beberapa menit untuk menyelesaikannya. Saya melakukan hal berikut:

  • Saya memiliki tabel pekerjaan dengan detail file yang diminta. Ketika pengguna meminta file, permintaan masuk dalam tabel itu dan pengguna dibawa ke halaman "status pekerjaan" yang mencantumkan semua pekerjaan mereka.
  • Saya memiliki tugas menyapu yang menjalankan semua pekerjaan luar biasa (metode kelas pada model Pekerjaan).
  • Saya memiliki instalasi rel yang terpisah di kotak lain yang menangani pekerjaan ini. Kotak ini hanya melakukan pekerjaan, dan tidak dapat diakses oleh dunia luar.
  • Pada kotak yang terpisah ini, tugas cron menjalankan semua pekerjaan luar biasa setiap 60 detik, kecuali pekerjaan masih berjalan dari permintaan terakhir.
  • Halaman status pekerjaan pengguna melakukan penyegaran otomatis untuk menunjukkan status pekerjaan (yang diperbarui oleh kotak pekerjaan saat pekerjaan dimulai, berjalan, kemudian selesai). Setelah pekerjaan selesai, tautan muncul ke file hasil.

Ini mungkin terlalu berat-tugas jika Anda hanya berencana untuk memiliki satu atau dua berjalan pada suatu waktu, tetapi jika Anda ingin skala ... :)


6



menelepon ./script/runner di latar belakang berfungsi paling baik untuk saya. (Saya juga sedang membuat generasi PDF.) Sepertinya denominator umum terendah, sementara juga menjadi yang paling sederhana untuk diterapkan. Berikut ini ulasan pengalaman saya.


4



Solusi sederhana yang tidak memerlukan tambahan Permata atau plugin adalah dengan membuat tugas Rake khusus untuk menangani pembuatan PDF. Anda dapat memodelkan proses pembuatan PDF sebagai mesin negara dengan kondisi seperti diajukan, pengolahan dan lengkap yang disimpan dalam tabel database model. Permintaan HTTP awal ke aplikasi Rails hanya akan menambahkan catatan ke tabel dengan diajukan kenegaraan dan kembali.

Akan ada tugas cron yang menjalankan tugas Rake kustom Anda sebagai proses Ruby terpisah, sehingga aplikasi Rails utama tidak terpengaruh. Tugas Rake dapat menggunakan ActiveRecord untuk menemukan semua model yang memiliki diajukan negara, mengubah negara menjadi pengolahan dan kemudian menghasilkan PDF yang terkait. Akhirnya, harus mengatur negara untuk lengkap. Ini memungkinkan panggilan AJAX Anda dalam aplikasi Rails untuk memantau keadaan proses pembuatan PDF.

Jika Anda memasukkan tugas Rake Anda your_rails_app/ lib / tugas maka ia memiliki akses ke model dalam aplikasi Rails Anda. Kerangka seperti itu pdf_generator.rake akan terlihat seperti ini:

namespace :pdfgenerator do
  desc 'Generates PDFs etc.'
  task :run => :environment do

    # Code goes here...
  end
end

Sebagaimana dicatat dalam wiki, ada beberapa kerugian pada pendekatan ini. Anda akan menggunakan cron untuk secara teratur membuat proses Ruby yang cukup berat dan pengaturan waktu dari tugas cron Anda akan membutuhkan penyetelan yang hati-hati untuk memastikan bahwa masing-masing memiliki waktu yang cukup untuk menyelesaikan sebelum yang berikutnya datang. Namun, pendekatannya sederhana dan harus memenuhi kebutuhan Anda.


2



Ini terlihat cukup lama. Namun, apa yang saya miliki di aplikasi saya, yang diperlukan untuk menjalankan beberapa Penghitung waktu mundur untuk halaman yang berbeda, adalah untuk digunakan Ruby Thread. Pengatur waktu harus terus berjalan bahkan jika halaman ditutup oleh pengguna.
 
  Ruby membuatnya mudah untuk menulis program multi-thread dengan kelas Thread. Ruby thread adalah cara yang ringan dan efisien untuk mencapai paralelisme dalam kode Anda. Saya harap ini akan membantu pengembara lain yang ingin mencapai latar belakang: paralelisme / layanan bersamaan dalam aplikasinya. Demikian juga Ajax membuatnya lebih mudah untuk memanggil tindakan [kebiasaan] khusus setiap detik.


2



Ini benar-benar terdengar seperti sesuatu yang Anda harus memiliki proses latar belakang berjalan daripada contoh aplikasi (penumpang / mongrel mana yang Anda gunakan) karena cara aplikasi Anda dapat tetap melakukan apa yang seharusnya dilakukan, melayani permintaan, sementara tugas latar belakang semacam itu, Workling bagus, menangani angka-angka. Saya tahu bahwa ini tidak berurusan dengan masalah kemajuan, tetapi kecuali itu benar-benar penting saya pikir itu adalah harga kecil yang harus dibayar.

Anda dapat meminta pengguna untuk mengklik tindakan yang diperlukan, meminta tindakan tersebut meneruskan permintaan ke antrean Workling, dan mengirimnya semacam pemberitahuan kepada pengguna saat selesai, mungkin email atau sesuatu. Saya tidak yakin tentang kepraktisan itu, hanya berpikir keras, tetapi poin saya adalah bahwa itu benar-benar tampak seperti itu harus menjadi tugas latar belakang semacam itu.


1



Saya menggunakan Windows Vista 64 bit untuk saya   mesin pengembangan; Namun, saya   mesin produksi adalah Ubuntu 8.04 LTS.   Haruskah saya mempertimbangkan beralih ke Linux   untuk mesin pengembangan saya? Akankah   solusi yang disajikan bekerja pada keduanya?

Sudahkah Anda mempertimbangkan menjalankan Linux dalam VM di atas Vista?


1



Saya sarankan untuk menggunakan Resque permata dengan itu status resque plug-in untuk proses latar belakang Anda yang berat.

Resque

Resque adalah pustaka Ruby yang didukung Redis untuk membuat pekerjaan latar belakang,   menempatkan mereka di beberapa antrian, dan memprosesnya nanti.

Resque-status

resque-status adalah ekstensi ke sistem antrean resque yang menyediakan   pekerjaan dilacak sederhana.

Setelah Anda menjalankan pekerjaan di pekerja Resque menggunakan ekstensi status resque, Anda akan bisa mendapatkan info tentang kemajuan yang sedang berlangsung dan kemampuan untuk membunuh proses tertentu dengan sangat mudah. Lihat contoh:

status.pct_complete #=> 0
status.status #=> 'queued'
status.queued? #=> true
status.working? #=> false
status.time #=> Time object        
status.message #=> "Created at ..."

Juga resque dan resque-status memiliki antarmuka web yang keren untuk berinteraksi dengan pekerjaan Anda yang sangat keren.


1