Usando o xhprof, notei que file_scan_directory()
leva mais de 10 segundos para executar quando a primeira página é carregada. Por que demoraria tanto tempo?
Esta é a saída do xhprofile:
7
performance
hknik
fonte
fonte
Respostas:
Parece que você foi afetado por um problema conhecido no Drupal 7 .
Observando essas funções, parece que está faltando um módulo ou talvez um único arquivo de um módulo. Dê uma olhada em drupal_get_filename () , ele chama drupal_system_listing (), que chama essa função se não conseguir encontrar o arquivo solicitado. Adicione um dpm (func_get_args ()) logo antes de chamar drupal_system_listing (), que deve informar qual arquivo não está sendo encontrado.
fonte
Há várias razões pelas quais esse problema pode surgir e, para minha grande consternação, agora me encontro um pouco familiarizado com essas razões. De maneira frustrante, se você percebeu esse problema após atualizar o núcleo do Drupal para 7.33 ou mais, isso pode ser um erro de digitação em qualquer módulo, mesmo que você não tenha atualizado esse módulo.
Módulos removidos da base de código
Você pode primeiro verificar o bug conhecido mencionado pelo @Berdir, especialmente se você tiver removido recentemente módulos "não utilizados" da base de código. Para descobrir se você possui módulos ativados, mas que foram removidos do sistema de arquivos, execute um script como o mencionado aqui - ou use o meu, escrito para uma instalação de vários sites em um sistema com drush, a ser executado do diretório base do Drupal:
ou o seguinte:
Se você encontrar um módulo que foi removido da base de código, siga as instruções nos problemas mencionados pelo @Berdir.
Erros de codificação
Caso contrário, é provável que sua situação seja causada por um erro de codificação, como um arquivo que foi removido, mas ainda está sendo adicionado por uma chamada drupal_add_js (do comentário 19 na edição # 1082892) ou por um erro de digitação infeliz em um módulo ou tema , por exemplo
imagecache_actions
(consulte https://drupal.org/node/2381357 ).De qualquer forma, para descobrir exatamente por que isso está acontecendo, você precisa saber exatamente qual arquivo o Drupal não pode encontrar. Assim, de acordo com o comentário de Berdir, você pode temporariamente cortar
drupal_get_filename
embootstrap.inc
adicionando uma chamada de log ou uma mensagem pouco antes da chamada paradrupal_system_listing()
. Se você tiver o módulo Devel instalado,dpm
ele funcionará; Caso contrário, você pode usardrupal_set_message
ou syslog. Exemplos:Depois de saber o que o Drupal está procurando, é uma boa aposta que você possa descobrir para onde ir a partir daí. Meu problema foi causado por uma chamada para incluir um arquivo do módulo inexistente
imagcache_actions
(observe o erro de digitação). Então, procureiimagecache_actions
na minha base de código (por exemplogrep -r imagcache_actions .
) e descobri que a versão 1.4 doimagecache_canvasactions.module
usa module_load_include fora de qualquer chamada de função, no escopo do arquivo, com um erro de digitação. Novamente, esse erro foi exposto somente após a atualização para o Drupal 7.33+. Descobri que um problema já havia sido criadoimagecache_actions
, aplicado o patch e estava de volta aos negócios.fonte
Eu tive um problema muito semelhante -
file_scan_directory()
estava matando o site. Acontece que umanode_modules
pasta enorme incorporada no meu tema personalizadogulp
estava sendo examinada a cada descarga de cache. Mover esses arquivos para fora da pasta do tema (e atualizar alguns caminhos no meu arquivo de gulpfile) pareceu corrigi-lo. Como alternativa: acho que você pode hackearfile.inc
:'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519
fonte
O
file_scan_directory()
é uma função recursiva que corresponde a todos os arquivos que correspondem a um determinado diretório. São usosis_dir()
eopendir()
chamadas PHP, que podem custar mais tempo em termos de chamadas do sistema de E / S. A inicialização simples do Drupal (por exemplotime drush ev ""
) pode chamarfile_scan_directory
milhares de vezes (dependendo da complexidade da hierarquia de pastas do Drupal, por exemplo, número de módulos e suas pastas).No meu caso, eu tinha ~ 1500 chamadas para
file_scan_directory
(24 segundos no total, consistindo em 2 chamadas dedrupal_system_listing
incommon.inc
, as outras chamadas foram divididas por chamadas recursivas parafile_scan_directory
si mesmo.Para melhorar o desempenho nas chamadas de E / S, você precisa implementar o cache do arquivo. Isso pode ser conseguido instalando e ativando o OPCache (
opcache.enable=1
) e ajustando suas configurações (consulte: Como usar o PHP OPCache? ). Também é recomendável usar o cache baseado em memória, como memcached / redis.Ao usar a interface da linha de comandos (como
drush
), você também deve habilitaropcache.enable_cli=1
.Após a alteração, você pode verificar os syscalls mais consumíveis usando alguns depuradores disponíveis.
Por exemplo
No Linux usando
strace
(hit Ctrl- Cao fim):No Unix usando
dtrace
(usando sondas estáticas DTrace do PHP ), por exemploVocê também pode otimizar
drupal_system_listing()
oufile_scan_directory()
implementar o cache estático, por exemplo,Ou para armazenar
file_scan_directory
chamadas em cachedrupal_system_listing()
, verifique o seguinte patch disponível em: file_scan_directory deve ser armazenado em cache .fonte