Eu tenho um controlador com uma ação que aceita solicitações pelo AJAX, faz alguma manipulação de dados e retorna alguns dados:
function publicDirectoryAjaxSearch(){
// Check the form token
JSession::checkToken('get') or die('Invalid Token');
// Don't show PHP errors in raw output
ini_set('display_errors', 'Off');
// Sort out the session status
$session = JFactory::getSession();
$session->set('getOrganisationsStatus', 'Searching...');
// Get orgs
$response = $this->doPublicDirectorySearch();
// Get the document object.
$document = JFactory::getDocument();
// Set the MIME type for JSON output.
$document->setMimeEncoding('application/json');
// Change the suggested filename.
JResponse::setHeader('Content-Disposition','attachment;filename="result.json"');
echo json_encode($response);
}
Esse método pode demorar um pouco, então estou usando JSession para armazenar uma variável de status getOrganisationStatus
que pode ser verificada periodicamente via AJAX para ver até que ponto o $this->doPublicDirectorySearch()
método ficou ...
function doPublicDirectorySearch(){
...
while($running)
$session->set('getOrganisationsStatus', 'Fetched '.$handled."/".$totalResults." results.");
...
}
No entanto, estou tendo alguns problemas. Se eu definir o manipulador de sessão de configuração global do Joomla como Banco de dados , a variável de sessão getOrganisationsStatus
sempre parecerá 'atrasar' uma solicitação de dados para trás. Por exemplo (na preparação para este exemplo, limpei todas as sessões existentes):
publicDirectoryAjaxSearch
publicDirectorySearchStatus
$this->doPublicDirectorySearch()
funciona através dos dadospublicDirectorySearchStatus
. A variável de sessão retornada está vazia (esta etapa se repete no intervalo)publicDirectoryAjaxSearch
solicitação de dados concluída. O método retorna o objeto JSONpublicDirectorySearchStatus
.) Os dados retornados (a variável de sessão) agora mostram o texto correto, conforme definido no método de solicitação de dados.Se eu definir a configuração global do Joomla para usar Nenhuma como manipulador de sessões (ou seja, o PHP é um manipulador baseado em arquivos), o script será bloqueado (como - PHP bloqueia o arquivo da sessão quando um script o acessa, então a chamada AJAX para descobrir o status precisa esperar até que o método de atualização da variável da sessão termine - derrotando um pouco o ponto ).
Onde eu estou errando? Como posso..
Todas as suas solicitações de página compartilham a mesma sessão do usuário. Portanto, se você chamar várias páginas, de forma assíncrona, na mesma sessão, poderá encontrar uma condição de corrida . http://en.wikipedia.org/wiki/Race_condition
Como PHP não é multithreading, não há mecanismos de bloqueio para evitar esses casos).
A melhor solução é evitar a condição: reorganize o loop principal e mova o controle para o lado do Ajax. Dessa maneira, o navegador chama uma inicialização , o loop interno (- === - =)) como quantas vezes for necessário e a finalização .