Se eu estiver conectado ao back-end do Magento e executar alguma tarefa que demore muito (pesquisa global em grandes catálogos, fluxo de dados demorado, etc.), meu navegador se recusará a carregar outras páginas de administrador apenas nesse navegador . Por que isso acontece e existe alguma ciência conhecida para soluções alternativas?
Ou seja, se eu
Faça login na página do painel do Magento
Abra uma segunda aba com qualquer página de administração do Magento
Execute uma pesquisa global de longa duração (simulada com uma chamada para
sleep(30)
no início deglobalSearchAction
) na primeira guiaTentativa de recarregar a segunda guia
Comportamento esperado: a segunda guia carrega o conteúdo da página imediatamente
Comportamento real: a segunda guia é carregada apenas quando a pesquisa global de longa duração é concluída
Alguém sabe, especificamente, por que isso acontece? (Meu palpite é que as solicitações do console de administração do Magento bloqueiam alguns recursos que o Magento precisa para inicializar, mas não sei o que é isso)
Alguém sabe de uma correção / solução alternativa?
fonte
Respostas:
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.
fonte