file_scan_directory () কার্যকর করতে প্রায় 10 সেকেন্ড সময় নেয়


10

এক্সএইচআরপিফ ব্যবহার করে আমি লক্ষ্য করেছি যে file_scan_directory()প্রথম পৃষ্ঠাটি লোড হয়ে গেলে সম্পাদন করতে 10 সেকেন্ডের বেশি সময় লাগে। কেন এত দীর্ঘ সময় নেওয়া উচিত?

এটি এক্সএইচপ্রোফাইলের আউটপুট:

স্ক্রিনশট


আপনি "ফাইল_স্ক্যান_নির্দেশ" "প্রথম পৃষ্ঠা" করতে পারবেন না, কারণ প্রথম পৃষ্ঠাটি ডাটাবেস সারণিতে একটি প্রবেশিকা, কোনও ফাইল-সিস্টেমের পথ নয়।
লেথারিয়ন

@ লেটারিয়ান আমার ধারণা আপনি আমার প্রশ্নকে ভুল বুঝেছেন। আমি বোঝাতে চাইছি যখন প্রথম পৃষ্ঠাটি লোড হয় তখন এই ফাংশনটি সময় নেয় আমি প্রশ্নটি সম্পাদনা করি।
hknik

নির্দিষ্ট সময় নিয়ে ফাংশনটির সাথে প্রথম পৃষ্ঠার কী আসলেই কিছু করার আছে? আপনি আসলে কোন ডিরেক্টরিটি স্ক্যান করছেন? ডিরেক্টরিতে কি আছে?
লেথারিয়ন

আহা! আমি ভেবেছিলাম আপনি নিজেই এই ফাংশনটি কল করেছিলেন এবং আপনি আরও বিশদ কেন সরবরাহ করলেন না তা ভেবে অবাক হলেন। বারদিরের উত্তরটি খুব যুক্তিসঙ্গত দেখাচ্ছে। :)
লেথারিয়ান

উত্তর:


14

দেখে মনে হচ্ছে আপনি ড্রুপাল 7-তে একটি পরিচিত সমস্যা দ্বারা প্রভাবিত হয়েছেন

সম্ভবত, আপনি একাধিক মডিউল অনুপস্থিত অবস্থায় পুনরায় স্ক্যানিং মডিউল ডিরেক্টরিটি এড়ানোর জন্য আঘাত করছেন । আপনার ইনস্টলেশনটিতে কিছু অনুপস্থিত মডিউল থাকলে এটি ঘটে। আপনার সিস্টেমের টেবিলটি পরীক্ষা করার চেষ্টা করুন:

SELECT name, filename FROM system WHERE type = 'module' AND status = 1 ORDER BY filename

এবং যে কোনও মডিউলগুলি এখনও সক্রিয় রয়েছে তবে ফাইল সিস্টেম থেকে অনুপস্থিত clean

সামগ্রিকভাবে, দ্রুপাল way এটির মতো দুর্ভাগ্যজনক কিছু প্রতিক্রিয়া বাদে দ্রুপাল then এরপরে আরও বেশি সংস্থানযুক্ত এবং স্ক্র্যাবলযোগ্য।

এই ফাংশনগুলির দিকে তাকালে, দেখে মনে হচ্ছে এটি কোনও মডিউল বা মডিউলটির একটি একক ফাইল অনুপস্থিত। কটাক্ষপাত আছে drupal_get_filename () , এটা drupal_system_listing (), যা এই ফাংশন কল কল যদি এটা অনুরোধ করা ফাইলটি খুঁজে পাচ্ছি না করে। এটি একটি dpm (func_get_args ()) যুক্ত করার আগে ড্রুপাল_সিস্টেম_লিস্টিং () বলার আগে, এটি আপনাকে জানায় যে এটি কোন ফাইলটি সন্ধান করছে না।


দুর্ভাগ্যক্রমে (!) কোনও ফাইল মডিউল ফাইল সিস্টেম থেকে অনুপস্থিত
hknik

তারপরে আপনার কলটি কোথা থেকে আসছে তা সন্ধান করতে হবে, সম্ভবত কোনও কাস্টম বা অবদান মডিউল কিছু ভুল করছে। File_scan_directory () এর প্যারেন্ট ফাংশনগুলির মাধ্যমে ক্লিক করুন এবং প্যারেন্ট ফাংশনগুলির তালিকা সহ প্রাথমিক পোস্টটি আপডেট করুন।
বারদির

যারা ফাংশন এ খুঁজছি, এটা নেই মত একটি মডিউল হয়তো বা একটি মডিউল একটি একক ফাইল অনুপস্থিত দেখুন। Drupal_get_filename: api.drupal.org/api/drupal/includes!bootstrap.inc/function/… এ একবার দেখুন । যদি অনুরোধ করা ফাইলটি খুঁজে না পায় তবে এটি ফাংশনটিকে কল করে। এটি একটি dpm (func_get_args ()) যুক্ত করার আগে ড্রুপাল_সিস্টেম_লিস্টিং () বলার আগে, যা আপনাকে জানায় যে এটি কোন ফাংশনটি সন্ধান করছে না।
বেরদির

@ বার্ডির আপনার শেষ মন্তব্যটি আপনার উত্তর হওয়া উচিত, কারণ এটি প্রাসঙ্গিক।
কিমলালুনো

"ড্রুপাল 7-তে জ্ঞাত সমস্যা" এবং "মডিউল ডিরেক্টরি পুনরুদ্ধার এড়ান" এর লিঙ্কগুলি নষ্ট হয়ে গেছে। উভয়ই প্রাক্তন স্ট্যাকেক্সচেঞ্জের উত্তর। কারও কি অন্য রেফারেন্স আছে?
rfay

4

এই সমস্যাটি উত্থাপিত হওয়ার বিভিন্ন কারণ রয়েছে এবং আমার চরম হতাশার জন্য আমি এখন নিজেকে এই কারণগুলি সম্পর্কে কিছুটা জ্ঞানী মনে করি। হতাশাজনকভাবে, আপনি যদি ড্রুপাল কোরকে 7.33+ তে উন্নীত করার পরে কেবল এই সমস্যাটি লক্ষ্য করেছেন, এটি কোনও মডিউলটিতে টাইপও হতে পারে, আপনি যদি এই মডিউলটি আপগ্রেড নাও করেন।

কোড বেস থেকে মডিউল সরানো হয়েছে

আপনি প্রথমে সেই পরিচিত বাগটি যাচাই করতে চাইতে পারেন যা @ বার্ডির উল্লেখ করেছেন, বিশেষত যদি আপনি সম্প্রতি কোড বেস থেকে "অব্যবহৃত" মডিউলগুলি সরিয়ে রেখেছেন। আপনার মডিউলগুলি সক্ষম রয়েছে কিনা তবে এটি ফাইল সিস্টেম থেকে সরিয়ে ফেলা হয়েছে কিনা তা জানতে আপনি এখানে বর্ণিত স্ক্রিপ্টটি চালাতে পারেন - বা ড্রাম সহ একটি সিস্টেমে মাল্টি-সাইট ইনস্টল করার জন্য লেখা আমার, ব্যবহার করতে পারেন ড্রুপাল বেস ডিরেক্টরি থেকে:

find sites -maxdepth 1 -iname '*.*' -type d | sed -rne 's:sites/(.+):echo \1; drush @\1 sqlq "select filename from system where status = 1" | grep "/" | sed -rne "s_(.+)_test -f \\1 || echo \\1_p" | bash:p' | bash

বা নিম্নলিখিত:

while read -r file; do [ -f "$file" ] || echo "$file is missing."; done < <(drush sqlq "SELECT filename FROM system WHERE status = 1")

আপনি যদি এমন কোনও মডিউল খুঁজে পান যা কোড বেস থেকে সরানো হয়েছে, তবে @ বারডির উল্লিখিত সমস্যাগুলির দিকনির্দেশগুলি অনুসরণ করুন।

কোডিং ত্রুটি

যদি এটি না হয় তবে আপনার পরিস্থিতি সম্ভবত কোডিং ত্রুটির কারণে ঘটেছে, যেমন একটি ফাইল যা সরানো হয়েছে তবে এখনও একটি দ্রুপাল_এডিডি_জেএস কল দ্বারা যুক্ত করা হয়েছে (ইস্যুতে # 1082892 ইস্যুতে মন্তব্য 19) বা মডিউল বা থিমের দুর্ভাগ্যজনক টাইপ উদাহরণস্বরূপ imagecache_actions( https://drupal.org/node/2381357 দেখুন )।

যাইহোক, কেন এটি ঘটছে তা নির্ধারণ করার জন্য, ড্রুপাল কোন ফাইলটি খুঁজে পাচ্ছে না তা ঠিক আপনার জানা দরকার। সুতরাং, Berdir এর মন্তব্য অনুযায়ী, আপনি সাময়িকভাবে হ্যাক করতে drupal_get_filenameমধ্যে bootstrap.incশুধু কল করার আগে একটি লগ বা বার্তা কল যোগ করে drupal_system_listing()। আপনার যদি ডেভেল মডিউল ইনস্টল থাকে তবে dpmকাজ করবে; যদি না হয়, আপনি ব্যবহার করতে পারেন drupal_set_messageবা syslog। উদাহরণ:

dpm(func_get_args());
drupal_set_message(implode(', ', func_get_args()));
syslog(LOG_WARNING, implode(', ', func_get_args()));

একবার আপনি যখন বুঝতে পারেন দ্রুপাল কী খুঁজছেন, তবে এটি একটি ভাল বাজি যে আপনি সেখান থেকে কোথায় যাবেন তা অনুধাবন করতে সক্ষম হবেন। অস্তিত্বহীন মডিউল থেকে একটি ফাইল অন্তর্ভুক্ত করার জন্য কল করার কারণে আমার সমস্যা হয়েছিল imagcache_actions(টাইপোট নোট করুন)। সুতরাং, আমি imagecache_actionsআমার কোডবেসে অনুসন্ধান করেছি (উদাঃ grep -r imagcache_actions .), এবং খুঁজে পেয়েছি যে 1.4 সংস্করণটি imagecache_canvasactions.moduleমডিউল_লোড_কেন্দ্রের কোনও ফাংশন কলের বাইরে, ফাইল স্কোপে একটি টাইপো সহ ব্যবহার করে। আবার, এই ত্রুটিটি কেবলমাত্র দ্রুপাল 7.33+ আপডেট করার পরে প্রকাশিত হয়েছিল। আমি দেখতে পেয়েছি যে একটি ইস্যু ইতিমধ্যে তৈরি হয়েছিল imagecache_actions, প্যাচ প্রয়োগ করেছিল এবং ব্যবসায় ফিরে এসেছিল।


2

আমার খুব অনুরূপ সমস্যা file_scan_directory()ছিল - সাইটটি মেরে ফেলা হয়েছিল। প্রতিটি ক্যাস ফ্লাশ স্ক্যান node_modulesকরার জন্য আমার কাস্টম থিমের মধ্যে এম্বেড করা হিউজ ফোল্ডারটি সক্রিয় করে gulp। থিম ফোল্ডারের বাইরে এই ফাইলগুলি সরিয়ে নিয়ে যাওয়া (এবং আমার গলফিলের কিছু পাথ আপডেট করা) আমার জন্য এটি ঠিক করেছে বলে মনে হয়েছিল। বিকল্পভাবে: আমি মনে করি আপনি হ্যাক করতে পারেন file.inc:

'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519


0

file_scan_directory()একটি recursive ফাংশন যা একটি প্রদত্ত ডিরেক্টরির জন্য মেলে সমস্ত ফাইল হয়। এটি ব্যবহার করে is_dir()এবং opendir()পিএইচপি কলগুলি আই / ও সিস্টেম কলগুলির ক্ষেত্রে সবচেয়ে বেশি সময় ব্যয় করতে পারে। সিম্পল ড্রুপাল বুটস্ট্র্যাপ (যেমন time drush ev "") আপনার file_scan_directoryকয়েক হাজার বার কল করতে পারে (আপনার ড্রুপাল ফোল্ডার স্তরক্রমের জটিলতার উপর নির্ভর করে, যেমন মডিউল এবং এর ফোল্ডারগুলির সংখ্যা)।

আমার ক্ষেত্রে আমার কাছে 1500 ডলার কল ছিল file_scan_directory(মোট ২৪ সেকেন্ডের মধ্যে 2 টি কল drupal_system_listingছিল common.inc, তারপরে অন্যান্য কলগুলি file_scan_directoryএটি নিজে থেকে পুনরাবৃত্ত কল দ্বারা বিভক্ত হয়েছিল ।

আই / ও কলগুলিতে পারফরম্যান্স উন্নত করার জন্য আপনাকে ফাইল ক্যাশে প্রয়োগ করতে হবে। এটি ওপ্যাচে ( opcache.enable=1এবং) সক্ষম করে এবং এর সেটিংসটিকে সামঞ্জস্য করে (দেখুন: কীভাবে পিএইচপি ওপিসি ব্যবহার করবেন? ) এর মাধ্যমে এটি অর্জন করা যেতে পারে । মেমোচেড / রেডিসের মতো মেমোরি-ভিত্তিক ক্যাচিং ব্যবহার করার পরামর্শ দেওয়া হয়।

কমান্ড-লাইন ইন্টারফেস (যেমন drush) ব্যবহার করার সময়, আপনার সক্ষম করা উচিত opcache.enable_cli=1

পরিবর্তনের পরে আপনি কিছু উপলব্ধ ডিবাগার ব্যবহার করে আরও বেশি গ্রাসকারী সিস্কলগুলি পরীক্ষা করতে পারেন।

যেমন

  • লিনাক্সে strace(হিট Ctrl- Cশেষ করতে) ব্যবহার করে :

    sudo strace -c -fp $(pgrep -n php)
  • ইউনিক্সে dtrace( পিএইচপি এর ডিট্রেস স্ট্যাটিক প্রোব ব্যবহার করে ) উদাহরণস্বরূপ

    sudo dtrace -n 'inline string NAME = "php"; syscall:::entry /(NAME == strstr(NAME, execname)) || (execname == strstr(execname, NAME))/ { @num[probefunc] = count(); }'

আপনি আরও অনুকূলকরণ drupal_system_listing()বা file_scan_directory()স্থির ক্যাশে প্রয়োগের মাধ্যমে বিবেচনা করতে পারেন , যেমন eg

--- a/includes/file.inc
+++ b/includes/file.inc
@@ -2104,6 +2104,8 @@ function file_download_access($uri) {
  *   'filename', and 'name' members corresponding to the matching files.
  */
 function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
+  static $dirs = array();
+
   // Merge in defaults.
   $options += array(
     'nomask' => '/(\.\.?|CVS)$/',
@@ -2120,7 +2122,12 @@ function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
       if (!preg_match($options['nomask'], $filename) && $filename[0] != '.') {
         $uri = "$dir/$filename";
         $uri = file_stream_wrapper_uri_normalize($uri);
-        if (is_dir($uri) && $options['recurse']) {
+
+        if (empty($dirs[$uri])) {
+          $dirs[$uri] = is_dir($uri);
+        }
+
+        if ($dirs[$uri] && $options['recurse']) {
           // Give priority to files in this folder by merging them in after any subdirectory files.
           $files = array_merge(file_scan_directory($uri, $mask, $options, $depth + 1), $files);

বা file_scan_directoryকলের কাছ থেকে কল পেতে drupal_system_listing(), তারপরে নিম্নলিখিত প্যাচটি উপলভ্য করুন: ফাইল_স্ক্যান_ডাইরেক্টরি ক্যাশে হওয়া উচিত

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.