এক্সএইচআরপিফ ব্যবহার করে আমি লক্ষ্য করেছি যে file_scan_directory()
প্রথম পৃষ্ঠাটি লোড হয়ে গেলে সম্পাদন করতে 10 সেকেন্ডের বেশি সময় লাগে। কেন এত দীর্ঘ সময় নেওয়া উচিত?
এটি এক্সএইচপ্রোফাইলের আউটপুট:
এক্সএইচআরপিফ ব্যবহার করে আমি লক্ষ্য করেছি যে file_scan_directory()
প্রথম পৃষ্ঠাটি লোড হয়ে গেলে সম্পাদন করতে 10 সেকেন্ডের বেশি সময় লাগে। কেন এত দীর্ঘ সময় নেওয়া উচিত?
এটি এক্সএইচপ্রোফাইলের আউটপুট:
উত্তর:
দেখে মনে হচ্ছে আপনি ড্রুপাল 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 ()) যুক্ত করার আগে ড্রুপাল_সিস্টেম_লিস্টিং () বলার আগে, এটি আপনাকে জানায় যে এটি কোন ফাইলটি সন্ধান করছে না।
এই সমস্যাটি উত্থাপিত হওয়ার বিভিন্ন কারণ রয়েছে এবং আমার চরম হতাশার জন্য আমি এখন নিজেকে এই কারণগুলি সম্পর্কে কিছুটা জ্ঞানী মনে করি। হতাশাজনকভাবে, আপনি যদি ড্রুপাল কোরকে 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
, প্যাচ প্রয়োগ করেছিল এবং ব্যবসায় ফিরে এসেছিল।
আমার খুব অনুরূপ সমস্যা file_scan_directory()
ছিল - সাইটটি মেরে ফেলা হয়েছিল। প্রতিটি ক্যাস ফ্লাশ স্ক্যান node_modules
করার জন্য আমার কাস্টম থিমের মধ্যে এম্বেড করা হিউজ ফোল্ডারটি সক্রিয় করে gulp
। থিম ফোল্ডারের বাইরে এই ফাইলগুলি সরিয়ে নিয়ে যাওয়া (এবং আমার গলফিলের কিছু পাথ আপডেট করা) আমার জন্য এটি ঠিক করেছে বলে মনে হয়েছিল। বিকল্পভাবে: আমি মনে করি আপনি হ্যাক করতে পারেন file.inc
:
'nomask' => '/(\.\.?|CVS|node_modules)$/', // https://www.drupal.org/node/2329453#comment-9360519
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()
, তারপরে নিম্নলিখিত প্যাচটি উপলভ্য করুন: ফাইল_স্ক্যান_ডাইরেক্টরি ক্যাশে হওয়া উচিত ।