Bagaimana API batch bekerja secara internal?


19

Saya mengalami masalah batas waktu menggunakan migrasi hari lain dan mulai bertanya-tanya bagaimana Batch API bekerja secara internal.

Cara saya memahaminya adalah bahwa dalam bentuknya yang paling sederhana Anda akan melewatkan array nilai (misalnya nids) dan fungsi untuk beroperasi pada nilai-nilai tersebut. API batch kemudian memproses sejumlah nilai-nilai itu dengan setiap permintaan sampai selesai.

Ketika batch berjalan, halaman tampaknya menggunakan permintaan Ajax untuk menunjukkan kemajuan operasi batch (% selesai dan pesan). Saya menganggapnya menunggu sampai permintaan selesai untuk memperbarui kemajuan dan kemudian memulai permintaan berikutnya segera setelah itu?

Jika halaman dengan permintaan batch ditutup, apakah pemrosesan batch berhenti? Apakah akan mulai lagi ketika URL yang sama dibuka lagi? Modul migrasi kadang berlanjut tetapi mungkin menggunakan antrian?

Jawaban:


40

Beginilah cara kerja batch (Berdasarkan Pemahaman saya)

1. Inisialisasi

  1. Inisialisasi pemrosesan batch. Berdasarkan konfigurasi klien (Peramban) apakah JavaScript diaktifkan atau tidak.
  2. Klien berkemampuan JavaScript diidentifikasi oleh cookie 'has_js' yang disetel di drupal.js. Jika tidak ada halaman yang mendukung JavaScript telah dikunjungi selama sesi browser pengguna saat ini, versi non-JavaScript dikembalikan.
  3. Jika JavaScript diaktifkan, Batch menggunakan permintaan ajax , menjaga koneksi tetap hidup di seluruh permintaan.
  4. Jika JavaScript tidak diaktifkan, Batch menggunakan menetapkan tag meta dalam html untuk membuat interval penyegaran reguler untuk menjaga koneksi tetap hidup di seluruh permintaan.

(Beginilah bilah kemajuan diperbarui pada progres Pekerjaan yang Dilakukan.)

Proses Batch

  1. Untuk memulai proses, Batch membuat Antrian dan menambahkan semua operasi (fungsi dan argumen) yang Anda tentukan dalam array batch seperti,

    $batch = array (
    'operations' => array(
      array('batch_example_process', array($options1, $options2)),
      array('batch_example_process', array($options3, $options4)),
      ),
    'finished' => 'batch_example_finished',
    'title' => t('Processing Example Batch'),
    'init_message' => t('Example Batch is starting.'),
    'progress_message' => t('Processed @current out of @total.'),
    'error_message' => t('Example Batch has encountered an error.'),
    'file' => drupal_get_path('module', 'batch_example') . '/batch_example.inc',
    );

    Selain itu ia juga menetapkan id batch yang unik di seluruh batch.

  2. Sekarang panggilan Batch mengklaim item Antrian satu per satu dan mengeksekusi fungsi yang didefinisikan dengan argumen yang didefinisikan di dalamnya.

  3. Ini adalah bagian penting, Fungsi (Operasi) yang mengimplementasikan operasi batch harus memotong data dan memproses data dengan sangat efisien mengingat batas Memori PHP, Time out . Gagal melakukannya akan berakhir pada masalah Anda.

Saya mengalami masalah batas waktu menggunakan migrasi hari lain dan mulai bertanya-tanya bagaimana batch API bekerja secara internal.

Fungsi Batch

Fungsi-fungsi yang menerapkan Batch harus mengambil hal-hal berikut dengan sangat hati-hati,

  • Jumlah Item dalam operasi untuk diproses seperti,

    if (!isset($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT nid) FROM {node}'));
    }
  • Membatasi jumlah item untuk diproses dalam satu panggilan fungsi seperti mengatur batas,

    // For this example, we decide that we can safely process 5 nodes at a time without a timeout.
    $limit = 5;
  • Perbarui proses ke pasca-pemrosesan seperti,

    // Update our progress information.
        $context['sandbox']['progress']++;
        $context['sandbox']['current_node'] = $node->nid;
        $context['message'] = t('Now processing %node', array('%node' => $node->title));
  • Menginformasikan mesin Batch apakah Batch selesai atau Tidak suka,

    // Inform the batch engine that we are not finished,
    // and provide an estimation of the completion level we reached.
    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
      $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }

Sebagian besar Poin di atas diurus operasi batch Core Drupal jika tidak ada dalam fungsi Implementing. Tetapi selalu terbaik untuk mendefinisikan dalam fungsi implementasi

Callback selesai jadi

  • Ini adalah panggilan terakhir yang dipanggil ketika didefinisikan dalam array batch Biasanya laporan tentang seberapa banyak diproses dll ...

JAWABAN

Jika halaman dengan permintaan batch ditutup, apakah pemrosesan batch berhenti? Apakah akan mulai lagi ketika url yang sama dibuka lagi? Modul migrasi kadang berlanjut tetapi mungkin menggunakan antrian?

Ya, idealnya itu harus memulai ulang batch dan seperti yang dikatakan di atas didasarkan pada fungsi yang Anda implementasikan.

Untuk menyelesaikan masalah PHP Time out Anda, gunakan Drush batch yang tersedia di modul migrasi, Tapi pertama-tama gali fungsi-fungsi kumpulan migrasi dan cobalah untuk memotong data pemrosesan Anda.


1
Jalan kaki yang luar biasa. Saya juga ingin menunjukkan bahwa batch mulai memproses selama apa, setidaknya untuk pengguna, tampaknya menjadi "Inisialisasi." layar. Artinya, jika diperlukan 4 detik untuk mengatur dan 10 detik untuk memproses item batch pertama, maka pengguna akan melihat proses "Inisialisasi." selama empat belas detik dalam contoh ini. Ini masuk akal karena pesan layar non-init pertama adalah "n selesai" yang hanya akan berfungsi setelah beberapa diproses. Jika ini salah, mohon koreksi saya!
texas-bronius

Juga, dari pengalaman saya. Jika Anda meninggalkan halaman operasi batch / chunk yang sedang dalam proses masih akan mengkonsumsi sumber daya sampai selesai. Itu tidak mematikan lagi pekerjaan batch tetapi tidak menyelesaikan yang sekarang.
Elijah Lynn

10

Jika halaman dengan permintaan batch ditutup, apakah pemrosesan batch berhenti?

Ya, itu akan dihentikan.

Apakah akan mulai lagi ketika url yang sama dibuka lagi? Modul migrasi kadang berlanjut tetapi mungkin menggunakan antrian?

Seperti yang Dinesh katakan tergantung pada implementasinya.

Anda harus menjalankan migrasi menggunakan drush, karena

Drush berjalan di baris perintah dan tidak tunduk pada batas waktu apa pun (khususnya, max_execution_time PHP tidak berlaku). Jadi, ketika Anda memulai proses migrasi berjalan melalui drush, itu hanya dimulai dan terus berjalan sampai selesai.

Saat menjalankan proses melalui antarmuka web, PHP max_execution_time (biasanya 30 detik jika tidak kurang) berlaku. Dengan demikian, untuk proses yang berjalan lama kita perlu menggunakan Batch API, yang mengelola pemecahan proses di beberapa permintaan. Jadi, proses migrasi akan mulai, berjalan selama 25 detik atau lebih, kemudian berhenti dan biarkan Batch API mengeluarkan permintaan halaman baru, di mana proses migrasi dimulai kembali, ad infinitum.

Jadi, memahami itu, mengapa Drush lebih baik?

Lebih cepat

Batch API memperkenalkan banyak overhead - mematikan dan memperbarui kembali permintaan halaman, proses migrasi perlu menjalankan semua konstruktor yang diperlukan lagi, koneksi database dibangun kembali dan pertanyaan dijalankan kembali, dll. Dan, untuk impor parsial, perlu memilih di mana ia tinggalkan - jika 500 catatan sumber pertama telah diimpor, ia perlu menemukan catatan 501. Bergantung pada format sumber Anda dan bagaimana konstruksinya, ini mungkin atau tidak skala - jika Anda menggunakan tanda air tinggi dengan sumber SQL, kueri itu sendiri dapat menghilangkan catatan sebelumnya dan mulai tepat di mana Anda tinggalkan. Jika tidak, maka Migrasikan perlu menggulir data sumber mencari catatan yang tidak diimpor pertama. Dengan, katakanlah, file XML besar sebagai sumber Anda,

Ini lebih bisa diandalkan

Menjalankan migrasi melalui browser Anda menambahkan desktop Anda, dan koneksi Internet lokal Anda, sebagai titik kegagalan. Kesalahan jaringan ketika Batch API pindah ke permintaan halaman berikutnya, browser crash, penutupan tab atau jendela yang salah semua dapat mengganggu migrasi Anda. Menjalankan dengan drush mengurangi komponen yang bergerak - Anda menghilangkan desktop dan koneksi internet lokal Anda sebagai faktor.

Itu lebih bermanfaat

Jika terjadi kesalahan saat menjalankan di Drush, jika ada pesan kesalahan yang berguna Anda akan melihatnya. Kegagalan menggunakan Batch API sering tertelan dan yang Anda lihat hanyalah "AJAX HTTP request yang benar-benar tidak berguna dihentikan secara tidak normal. Informasi debug berikut. Path: / batch? Id = 901 & op = lakukan StatusText: ResponseText: ReadyState: 4".

Anda dapat menemukan informasi lebih lanjut tentang ini di sini .

Sementara itu jika Anda ingin menjalankan batch bahkan jika jendela browser ditutup, pertimbangkan modul Background Process . Ini memiliki Batch Background submodule yang melakukan trik.

Modul ini mengambil alih API Batch yang ada dan menjalankan pekerjaan dalam proses latar belakang. Ini berarti bahwa jika Anda meninggalkan halaman batch, pekerjaan berlanjut, dan Anda dapat kembali ke indikator progres nanti.


wow, menggunakan pemabuk untuk bermigrasi membuat peningkatan besar. Saya harus bermigrasi ke situs langsung dan itu menempatkan beban jauh lebih sedikit ke sistem! Terima kasih!
uwe

0

Memahami Batch API dan modul-modul ini dengan hati-hati akan membantu Anda:

1- Progers Ini adalah upaya untuk menerapkan kerangka kerja umum untuk melacak kemajuan apa pun

2- Kemajuan latar belakang mengambil alih API Batch yang ada dan menjalankan pekerjaan batch dalam proses latar belakang

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.