2011-10-07 19 views
2

我有一個名爲/實施例/ 1 /重複 上有一個Ajax形式序幕頁/實施例/ 1/run_duplicate消息到控制器水平AJAX目的

控制器方法run_duplicate運行Example.duplicate(會話) 我通過會話,我知道這是一個神聖的禁忌。

重複的模型代碼大致是:

def duplicate(session) 
    session[:duplicate] = 0 
    duplicate_foobars 
    session[:duplicate] = 1 
    duplicate_snafus 
    session[:duplicate] = 2 
    duplicate_widgets 
    session[:duplicate] = 3 
end 

我這是做一個長輪詢重複的頁面上的其他控制器的方法:/例子/ 1/check_dupe_status 的目的是爲了得到更新的狀態會話[:重複],調整進度報告, 並通過ajax報告給用戶,以便他們可以看到Example.duplicate()的進度。

會話沒有按照我希望的方式更新。我可以看到代碼運行,但會話不更新,因此/ examples/1/check_dupe_status從不知道任何事情已經啓動。

鑑於我從一開始就犯了這個錯誤,通知用戶有關Example.duplicate()狀態的正確方法是什麼?

回答

1

聽起來就像你有兩個單獨的請求,一個寫入會話,另一個嘗試同時讀取會話。那是對的嗎?如果不是,請停止閱讀。

這不能工作,因爲「會話」只是一個cookie - HTTP響應的頭部以Cookie的形式下載到瀏覽器,然後在下一個請求中重新上傳,然後在下一個響應中重新下載,廣告nosium。在你的代碼,這裏是操作順序:

  1. /例子/ 1/run_duplicate寫道: 「0」 到什麼本質上是一個Ruby的Hash,代表您的會話cookie

  2. /例子/ 1/check_dupe_status從會話cookie 中讀取剛從您的瀏覽器發出的請求中的值。它可能根本沒有任何內容:重複的,所以它會顯示爲空白。

  3. /例子/ 1/run_duplicate 「1」 寫在紅寶石會話哈希

  4. /例子/ 1/check_dupe_status讀取,再次,這是請求發送會話cookie - 一切都沒有改變

  5. /例子/ 1/run_duplicate寫道: 「2」 的紅寶石會話哈希

  6. /例子/ 1/check_dupe_status從它最初發送會話cookie讀取 - 沒有變化

  7. /examples/1/run_duplicate將「3」寫入Ruby會話哈希,並且請求結束,將會話作爲cookie返回,其值爲3:duplicate。

  8. /例子/ 1/check_dupe_status仍然坐在那裏,像一個dufus,閱讀它最初發送

在某一點上的空白會話cookie,/例子/ 1/check_dupe_status可能超時,並且可能返回會話cookie。但猜猜怎麼了?由於:從未在中設置重複會話Cookie,它將覆蓋瀏覽器中的一個,並且:在您發送的下一個請求中,重複項將爲空白。

希望我明確表達過。基本上,你在cookies中遇到了競爭條件,如果你從同一瀏覽器發送併發請求,這很難克服。

處理此問題的最佳方法是將重複的0,1,2等值寫入某個數據庫表。您的長輪詢請求可能只是讀出數據庫。可能效率稍低一點,但它當然有它可以工作的優點。

+0

謝謝...會議居住在數據庫中,所以我的一些部分停止使用關於何時寫數據的常識:)。我希望避免在數據庫中創建自己的空間,但我擔心你可能是對的。要讓其他人檢查,但那可能是我必須要做的。 – cgr

+0

不知道Rails在哪一刻將會話更改寫入數據庫。會話對象被封裝然後Base64'd,因此在技術上可以手動讀取數據。雖然可能會很棘手。但我的猜測是,Rails只在請求結束時將會話更改寫入數據庫,這使得這種猜測在你的案例中是學術性的。雖然可能值得研究。 – bioneuralnet