我有一个中等大小的应用程序,它使用Data.Acid
实现持久性,并且我遇到了一种情况,需要为下一版本的服务器更新我的一个Update
事件的实现。也就是说,我有类似的东西
myUpdate :: Update MyState ()
myUpdate = <some outdated implementation>
现在,很明显,我不能随意更改实现,因为这会破坏我的交易历史记录,所以我想知道人们通常是如何处理的。我认为我的选择是:
停止服务器。为我的
AcidState
运行createCheckpoint
。更新Event
实现,然后重新启动服务器。由于我们是从新的快照加载的,因此更改后的Update
永远不会触发旧事件。用新名称创建一个新的
Update
(如myUpdate_v2
),并更新我的服务器逻辑,使其在任何地方都只使用myUpdate_v2
,而不是原始的myUpdate
。
我认为这两种选择都有其优点。(1) 更好,因为我不需要在代码库中保留旧功能,但对于我更新的每台服务器,都必须非常小心,否则会有损坏数据的风险。(2) 更安全(尤其是如果我从模块的导出中删除旧的myUpdate
,这样我就可以确保不会在任何地方意外使用旧的实现),但在其他方面感觉有点难看。
有更好的方法吗?我认为这是我在一个长期项目中肯定会遇到的事情,所以我希望有一个好的、标准的工作流程来将更改应用于我的事件的实现。
解决方案是不使用像"alter"这样的高阶函数。acid状态的好处(acid保证、远程运行代码等)是以只使用可串行化数据为代价的。这限制不太可能被取消。
通常这不是什么大问题;只需专门处理您的代码。如果这还不能解决问题,也许你想把你的状态保持在MVar中。