Masalahnya disebabkan oleh kunci yang ditempatkan oleh pengendali sesi PHP. Jadi bukan Magento yang secara eksplisit mengunci sesuatu dan mencoba memblokir permintaan admin, tetapi hampir efek samping per-se penyimpanan sesi berbasis file.
Kunci write sedang ditempatkan pada file data sesi bila dibuka oleh awal (lama berjalan) permintaan, menyebabkan permintaan kedua untuk blok sampai mengunci dilepaskan ketika panggilan session_start
diMage_Core_Model_Session_Abstract_Varien::start
Ini 100% dapat direproduksi. Saya menggunakan metode yang sama yang Anda lakukan, menambahkan sleep(30)
ke atasMage_Adminhtml_IndexController::globalSearchAction
Perlu dicatat adalah bahwa ini tidak dapat direproduksi jika Anda menggunakan penyimpanan sesi db. Setelah saya menemukan akar penyebabnya, saya mengatur kotak pasir ke penyimpanan sesi db dan tidak bisa lagi mereproduksi masalah. Jadi pengendali sesi db Magento tampaknya tidak menggunakan penguncian tingkat baris untuk mengunci sesi menulis. Saya menemukan ini menarik, karena memiliki potensi kehilangan data sesi karena aplikasi ini jelas tidak memperhitungkan beberapa utas menulis ke sesi yang sama. Catatan untuk Pembaca: Saya tidak akan pernah menggunakan penyimpanan sesi db dalam produksi untuk mencoba dan menyelesaikan ini, itu hanya baik untuk membebani database MySql Anda.
Saya tidak mencoba mereproduksi perilaku menggunakan sistem penyimpanan sesi berbasis memori seperti Redis, tetapi tebakan saya adalah bahwa mengunci catatan di toko sesi mungkin diabaikan dalam hal ini juga.
Ada beberapa teknik yang bisa digunakan untuk menghindari hal ini seperti menggunakan session_write_close
untuk melepaskan kunci sebelum Anda memulai pekerjaan yang sudah berjalan lama. Tetapi ini juga akan mencegah Anda dari menulis ke sesi karena Anda baru saja menutupnya. Jadi sepertinya tidak akan mudah diimplementasikan di seluruh papan di Magento, tetapi berpotensi dapat diimplementasikan pada rute / pengendali tertentu.
Teknik saya untuk menyematkan ini sebagai penyebab utama adalah mengaktifkan Xdebug profiler dan memeriksa file "cachegrind". Setelah permintaan kedua selesai, saya memuat file output (~ 25 MB log) ke MacCallGrind dan menelusuri jejak yang mengikuti jejak panggilan di mana waktu inklusif adalah 28 detik atau lebih besar. Ini akhirnya membawa saya ke session_start
panggilan yang membutuhkan waktu ~ 28 detik untuk berjalan, memberi saya poin yang bagus untuk penelitian.
EDIT: Bagi yang berminat, saya telah memposting tangkapan layar file "cachegrind" yang dilihat di MacCallGrind di Twitter.