2011-07-25 21 views
1

我的一個Rails應用的是Rails 2.2的應用程序有一個大的代碼庫。突然之間,開發模式似乎非常慢。這特別是由於config/environments/development.rb載入我的Rails在開發模式代碼庫以年齡

config.cache_classes = false

選項 - 當我設置爲true,那麼它會恢復正常。我期望缺乏緩存使其減速,但放緩我看到的量是荒謬的:有時會有30秒鐘的等待什麼開始在日誌中發生之前!一旦我看到開始發生在日誌文件中的東西,那麼頁面構建正常進行。我認爲這最近剛剛開始發生,但我不知道我能做些什麼來觸發它。

有誰知道我可以調查這個問題?我現在所要做的就是在日誌文件中沒有任何事情發生的30秒內。

任何指針

感激 - 最大

編輯 - 只注意到,當我關閉mongrel_rails(我使用運行在開發模式下的應用程序),我得到這個消息: Mon Jul 25 16:28:06 +0100 2011: Reaping 5 threads for slow workers because of 'shutdown'

這可能解釋瘋狂的減速,但我不知道爲什麼會有5個線程在運行。

EDIT2 - 這個程序是在Ruby 1.8.6 RVM運行,但切換回系統紅寶石(也1.8.6)沒有幫助。

EDIT3 - 只是做了一個實驗,在我的控制檯reload!需要28秒。所以這絕對是問題所在。我只是不明白爲什麼它需要這麼長時間。

+0

只適用於Rails3:https://github.com/paneq/active_reload – apneadiving

+0

你最近從ruby 1.8切換到1.9了嗎? – house9

+0

@ house9 - 不,它是一個紅寶石1.8.6環境,通過RVM加載。我想知道是否是由於切換到rvm引起的,我剛剛爲這個應用程序做了最近的改變,但是將rvm切換回系統並再次啓動應用程序沒有任何區別。 –

回答

1

我發現是什麼導致它,它是相當驚人的。答案

短版:

到我的應用程序的路徑已經得到了很長時間,這使得正則表達式的地方需要很長的時間來檢驗含有文件路徑的字符串。

回答長版:

一個瘋狂的調試任務*後來我發現違規行:它在lib/localization.rb 56行:

filename =~ /(([a-z]+_?)+)\.yaml$/ 

它運行這一行兩次對我來說,一旦對於lang文件夾中的每個yaml文件。什麼是真正的堅果是,「文件名」的值是

"/home/max/work/rails_apps/e_learning_resource_container/e_learning_resource/lang/en.yaml"

"/home/max/work/rails_apps/e_learning_resource_container/e_learning_resource/lang/localizations.yaml"

,如果我在我的控制檯運行鍼對這個正則表達式,我得到了大規模的延遲有以及。所以,問題是針對這些特定的字符串測試正則表達式。我只是做了一些實驗,爲需要多長時間正則表達式來完成的,你可以看到,它的倍增時間與每個額外的字母:從IRB(所以沒有什麼與我的應用程序做,只是普通的IRB)

ruby-1.8.6-p420 :023 > 10.times do |i| 
ruby-1.8.6-p420 :024 >  string = "#{string1}#{"a"*i}#{string2}" 
ruby-1.8.6-p420 :025?>  time = Time.now 
ruby-1.8.6-p420 :026?>  string =~ /(([a-z]+_?)+)\.yaml$/ 
ruby-1.8.6-p420 :027?>  puts "#{string} -> #{Time.now - time}s" 
ruby-1.8.6-p420 :028?> end 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_/lang/en.yaml -> 0.133935s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_a/lang/en.yaml -> 0.149782s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aa/lang/en.yaml -> 0.198117s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaa/lang/en.yaml -> 0.316208s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaa/lang/en.yaml -> 0.501882s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaa/lang/en.yaml -> 0.896808s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaa/lang/en.yaml -> 1.707035s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaa/lang/en.yaml -> 3.322242s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaaa/lang/en.yaml -> 6.613822s 
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaaaa/lang/en.yaml -> 13.399231s 

所以,正則表達式開始真正與字符串鬥爭。如果我改變了正則表達式,以便它的

/([a-z]+_?)\.yaml$/

,而不是

/(([a-z]+_?)+)\.yaml$/

,即去除(+)內括號,那麼它的罰款:超級快。

在localization.rb中添加了這個謎題,這個違規行是沒用的!下面是一個包含該行的整個塊:

Dir[RAILS_ROOT + '/lang/*.yaml'].each do |filename| 
    filename =~ /(([a-z]+_?)+)\.yaml$/ 
    hash = YAML::load(File.read(filename)) 
    file_charset = hash['file_charset'] || 'ascii' 
    lang = $1 

    # convert string keys to symbols 
    symbol_hash = Hash.new 
    Iconv.open(CONFIG[:web_charset], file_charset) do |i| 
    hash.each do |key, value| 
     symbol_hash[key.to_sym] = i.iconv(value) 
     if key =~ /^active_record_errors_(.*)/ 
     I18n.t("activerecord.errors.messages")[$1.to_sym] = 
      symbol_hash[key.to_sym] 
     end 
    end 
    end 

上線2的正則表達式在這裏測試字符串,但並沒有對結果什麼。也就是說,它不

if filename =~ etc 
    ...do something 

它只是測試中,它沒有明顯的原因。所以,我們已經得到了一個正則表達式,可以用任何理由使用長字符串。雙重失敗。這可能是這個模塊的舊版本,我甚至不知道它是如何進入我們的代碼庫,說實話。關閉以便爲我的固定版本(僅刪除該行)提出請求。 *如果有人想知道我瘋狂的調試任務包括什麼,我做了以下操作來在我的應用程序中爲每個rb文件的開始和結束添加調試行。

#get every rb file in the working folder 
old_filecount = nil 
files = [] 
fstring = "*/" 
count = 0 
folder = "./" 
while old_filecount != files.size 
    old_filecount = files.size 
    files += Dir[File.join(folder,fstring*count, "*.rb")] 
    count += 1 
end 
#spam debugging into start and end of every file 
files.each do |file| 
    `sed '1i\\\nputs \"#\{Time.now} - #\{__FILE__}:#\{__LINE__}\"\' #{file} > tmp.txt;mv tmp.txt #{file}` 
    `echo \";puts \\\"#\{Time.now} - #\{__FILE__}:#\{__LINE__}\\\"\" >> #{file}` 
end 

hacky呃。

+0

這條線與正則表達式做一些事情。匹配正則表達式設置全局變量$ 1,$ 2等等。變量$ 1稍後分配給'lang'。但是,以這種方式使用全局變量是一種非常糟糕的編程習慣。它看起來像'他們'認爲YAML :: load和File.read不使用regexen,永遠不會。 – Arsen7

+0

啊......對。我同意這是糟糕的編碼,不僅僅是因爲使用全局變量不受歡迎,而且因爲它實際上並不明顯。有趣的是,我無法找到本地化模塊甚至來自哪裏 - 我當時的應用程序中唯一的工程師的同事不記得添加它。我的猜測是,在我們開發我們的應用程序時(這是一款Rails 2.2.2應用程序),它是Rails的一部分,但我一直認爲這會讓它在互聯網上更容易找到。 –

相關問題