2013-12-19 44 views
59

我有一箇中等大小的應用程序,它使用Data.Acid來實現持久性,而且我遇到了需要更新下一個事件Update事件之一的情況服務器的版本。即我有一些像如何處理在使用Data.Acid時更改事件的實現

myUpdate :: Update MyState() 
myUpdate = <some outdated implementation> 

現在,很明顯我不能只是改變了實施隨意,因爲它會破壞我的交易記錄,所以我想知道人們通常怎麼處理這個問題。我看到它的方式有:

  1. 停止服務器。爲我的AcidState運行createCheckpoint。更新Event實現,然後重新啓動服務器。由於我們從一個新的快照加載,所以更改的Update不應觸發舊事件。

  2. 使用新名稱(如myUpdate_v2)創建一個新的Update和更新我的服務器邏輯,只使用myUpdate_v2隨處可見,而不是原來的myUpdate的。

我覺得這兩個選項都有它們的優點。 (1)更好,因爲我不需要在我的代碼庫中保留舊功能,但必須非常小心地爲每個更新的服務器執行操作,否則我可能會損壞數據。 (2)更安全(特別是如果我從模塊的輸出中刪除舊的myUpdate,所以我可以確定我不會意外地在任何地方使用舊的實現),但是否則會感覺有點難看。

有沒有更好的方法來做到這一點?我認爲這是我在一個長期項目中肯定會遇到的問題,所以我希望有一個很好的標準工作流程來應用對事件實施的更改。

+0

它是否正在改變MyState數據結構或只是實際的「寫入磁盤」之前的邏輯? – schellsan

+1

這兩個變化都很常見,但使用'SafeCopy'遷移來管理'MyState'數據結構的變化是微不足道的。但是,當'Data.Acid'通過事務日誌時,沒有更新邏輯的類似機制。 – shang

回答

1

解決方案是不使用'更改'等高階函數。酸狀態(ACID保證,遠程運行代碼等)的好處僅以使用可串行化數據爲代價。這種限制不太可能被解除。

通常這不是一個大問題;只是專門化你的代碼。如果這不能削減它,也許你想保持你的狀態在MVar中。

相關問題