2012-12-21 78 views
1

燒杯測試系統包含一個central scheduler,它根據配方中定義的各種標準將排隊配方分配到可用系統。緩存讀取,使用SQL Alchemy立即寫入

這是通過不斷循環當前配方隊列並尋找可處理該配方的可用系統來處理的。由於此方法查詢從數據庫中爲每個配方檢索更新後的系統狀態信息,因此遇到競爭狀況,即隊列中的任務有時會錯誤地在系統正在運行時可用的系統中首次出現。例如,假設我們有2個系統A和B,配方1(需要系統A),2(它可以在任一個上運行),3(也可以在任一個上運行)。當調度階段開始時,系統A已經很忙,因此配方1沒有可用的系統,我們繼續查看配方2並將其分配給系統B.在後臺,系統A完成它正在做的事情並將自己標記爲在數據庫中可用。調度程序現在繼續考慮配方3,看到系統A可用並將配方3分配給系統A.配方3已設法跳過隊列並聲明系統A,即使配方1應該已經提供。

我試圖想出一個近期修復這不涉及完全重新設計調度邏輯(雖然我們也在探討一些較長期的想法)。

目前我所擁有的最佳解決方案是在調度階段開始時將單獨的SQL Alchemy會話純粹打開爲數據庫狀態的緩存,以及調度程序所做的任何系統可用性狀態更改。該交易將在計劃傳遞結束時中止。在調度過程中,所有狀態更改都將按正常方式寫入數據庫,但也需要寫入高速緩存連接。

雖然這看起來真的很醜,所以我想知道如果有人有任何更好的想法如何處理這與SQL鍊金術。

+0

Donald Stufft發表的評論:如果我們每次將配方分配給系統時從配方隊列的開頭重新開始,那麼簡單的讀取隔離就足夠了。但是,考慮到調度程序目前的工作方式,該想法跨入「重新設計調度邏輯」的領域。 – ncoghlan

回答

0

經過一段時間的思考後,我意識到核心一致性問題在於,當系統完成任務時,即使當前有可能執行的排隊配方,它實際上在數據庫中被標記爲空閒在那個系統上。

我們需要做的是確保如果有可以在該系統上執行的配方,系統會立即重新分配到隊列中的第一個配方,而不是放回空閒池。同樣,如果一個新系統被添加或放回到自動模式,那麼我們立即分配它一些工作,而不是讓它進入空閒池。

因此,主調度循環最終只會處理分配新配方的任務,這些新配方會進入系統當前處於空閒狀態,而排隊配方到系統的分配將更多地由事件驅動。

此時,這只是管理併發訪問數據庫的典型問題,以確保兩個系統不會開始嘗試處理相同的配方。