Si he iniciado sesión en el backend de Magento y realizo alguna tarea que lleva mucho tiempo (búsqueda global en catálogos grandes, flujo de datos de larga ejecución, etc.), mi navegador web se negará a cargar otras páginas administrativas solo en ese navegador . ¿Por qué sucede esto? ¿Existe alguna ciencia conocida para soluciones alternativas?
Es decir, si yo
Inicie sesión en la página del panel de Magento
Abra una segunda pestaña con cualquier página de administración de Magento
Realice una búsqueda global de larga duración (simulada con una llamada al
sleep(30)
inicio deglobalSearchAction
) en la primera pestañaIntenta volver a cargar la segunda pestaña
Comportamiento esperado: la segunda pestaña se carga con el contenido de la página inmediatamente
Comportamiento real: la segunda pestaña solo se carga una vez que se completa la búsqueda global de larga duración
¿Alguien sabe, específicamente, por qué sucede esto? (Supongo que las solicitudes de la consola de administración de Magento bloquean algunos recursos que Magento necesita para arrancar, pero no sé qué es eso)
¿Alguien sabe de una solución / solución?
fuente
Respuestas:
El problema es causado por un bloqueo colocado por el controlador de sesión PHP. Por lo tanto, no se trata de que Magento bloquee explícitamente algo e intente bloquear las solicitudes de administración, sino casi un efecto secundario per-se del almacenamiento de sesión basado en archivos.
Un bloqueo de escritura se lo coloca en el archivo de datos de sesión cuando se abre por la solicitud inicial (de larga duración), haciendo que la segunda solicitud al bloque hasta que el bloqueo se libera cuando se llama
session_start
enMage_Core_Model_Session_Abstract_Varien::start
Esto es 100% reproducible. Usé el mismo método que usaste, agregando un
sleep(30)
a la parte superior deMage_Adminhtml_IndexController::globalSearchAction
Vale la pena señalar que esto no se puede reproducir si está utilizando el almacenamiento de sesión db. Después de encontrar la causa raíz, configuré un sandbox para el almacenamiento de sesión db y ya no pude reproducir el problema. Por lo tanto, los manejadores de sesión de db que Magento aparentemente no utiliza el bloqueo de nivel de fila para bloquear las escrituras de sesión. Esto me parece interesante, ya que tiene el potencial de pérdida de datos de la sesión, ya que la aplicación obviamente no tiene en cuenta múltiples hilos que escriben en la misma sesión. Nota para los lectores: nunca usaría el almacenamiento de sesión db en producción para tratar de resolver esto, solo es bueno para sobrecargar su base de datos MySql.
No intenté reproducir el comportamiento utilizando sistemas de almacenamiento de sesión basados en memoria como Redis, pero supongo que el bloqueo de los registros en el almacén de sesión probablemente también se pasó por alto en estos.
Hay técnicas que podrían emplearse para evitar esto, como usar
session_write_close
para liberar el bloqueo antes de comenzar un trabajo de larga duración. Pero esto también le impediría escribir en la sesión ya que la acaba de cerrar. Por lo tanto, no es probable que se implemente fácilmente en todos los ámbitos en Magento, pero podría implementarse en rutas / controladores específicos.Mi técnica para fijar esto como la causa raíz era habilitar el perfilador Xdebug y examinar el archivo "cachegrind". Una vez que se completó la segunda solicitud, cargué el archivo de salida (~ 25 MB de registro) en MacCallGrind y profundicé en el seguimiento siguiendo la ruta de las llamadas donde el tiempo de inclusión fue de 28 segundos o más. Esto finalmente me llevó a la
session_start
llamada, que tardó unos 28 segundos en ejecutarse, lo que me dio un gran punto para investigar.EDITAR: Para los interesados, publiqué una captura de pantalla del archivo "cachegrind" visto en MacCallGrind en Twitter.
fuente