O problema é causado por um bloqueio colocado pelo manipulador de sessões PHP. Portanto, não é o Magento que bloqueia explicitamente algo e tenta bloquear solicitações de administrador, mas quase um efeito colateral per-se do armazenamento de sessão baseado em arquivo.
Um bloqueio de gravação está sendo colocado no arquivo de dados da sessão quando ele é aberto pela inicial (de longa duração) pedido, fazendo com que o segundo pedido para o bloco até que o bloqueio é liberado quando ele chama session_start
emMage_Core_Model_Session_Abstract_Varien::start
Isso é 100% reproduzível. Eu usei o mesmo método que você, adicionando um sleep(30)
ao topoMage_Adminhtml_IndexController::globalSearchAction
Vale notar que isso não pode ser reproduzido se você estiver usando o armazenamento de sessão do db. Depois de encontrar a causa raiz, configurei uma sandbox para armazenamento de sessão no banco de dados e não consegui mais reproduzir o problema. Portanto, os manipuladores de sessão no banco de dados Magento aparentemente não usam o bloqueio no nível da linha para bloquear gravações de sessão. Acho isso interessante, porque tem o potencial de perda de dados da sessão, pois o aplicativo obviamente não está respondendo por vários threads gravados na mesma sessão. Nota para os leitores: eu nunca usaria o armazenamento de sessões db na produção para tentar resolver isso, isso é bom apenas para sobrecarregar o banco de dados MySql.
Não tentei reproduzir o comportamento usando sistemas de armazenamento de sessões baseados em memória, como Redis, mas meu palpite é que o bloqueio dos registros no repositório de sessões provavelmente também foi ignorado.
Existem técnicas que podem ser empregadas para evitar isso, como usar session_write_close
para liberar o bloqueio antes de iniciar um trabalho de longa duração. Mas isso também impediria que você escrevesse para a sessão, uma vez que você a fechou. Portanto, não é provável que seja prontamente implementado no Magento, mas pode ser implementado em rotas / controladores específicos.
Minha técnica para fixar isso como causa principal foi habilitar o criador de perfil Xdebug e examinar o arquivo "cachegrind". Depois que a segunda solicitação foi concluída, carreguei o arquivo de saída (~ 25 MB de log) no MacCallGrind e procurei o rastreamento seguindo o caminho das chamadas em que o tempo inclusivo era de 28 segundos ou mais. Isso me levou à session_start
ligação que levou cerca de 28 segundos para ser executada, o que me deu um ótimo ponto para pesquisar.
EDIT: Para os interessados, publiquei uma captura de tela do arquivo "cachegrind" exibido no MacCallGrind no Twitter.