我正在开发一个 Yesod 应用程序,其中许多应用程序请求将导致从 3rd-party API 获取数据。获取的数据只会在后续请求期间使用——也就是说,触发 API 调用的请求可以在不等待调用完成的情况下完成。
一条给定的数据xyz
不要被获取和存储两次,这一点很重要,但应用程序的本质是多个客户通常会xyz
同时对这些数据感兴趣。如果我让每个应用程序线程查询数据库以查看是否xyz
已获取,即使规模不大,我也会开始看到与并发相关的问题。即使我要编写一堆代码来处理与并发相关的完整性问题——不好玩,而且很难确定我已经涵盖了所有情况——以这种方式滥用昂贵的数据库查询也是一种不好的做法。
在我看来,一个不错的选择是让所有 App 线程将请求(“确保已获取 xyz 数据”)发布到 AMQP 队列,一个或多个“后台工作”类型的进程将订阅该队列。
在这个线程中,Greg Weber 建议使用双包布局,其中两个包都具有“我的持久层”作为依赖项。他提到我可以使用符号链接或hs-source-dir
s 来避免维护“持久层”代码的两个副本。
在高层次上,Greg 所描述的内容对我来说非常有意义,但我对 Haskell 比较陌生,我担心我需要一段时间才能弄清楚细节。有人可以更详细地为我安排吗?
- 包目录应该如何布局?(究竟是哪些文件构成了我的持久层?)
- .cabal 文件应该是什么样子?
- 一旦它们以这种方式布局,我是否需要更改我的(脚手架站点)源文件导入我的持久模型的方式?
另一部分是:您会如何推荐编写 BackgroundJobs 流程?除了 Yesod 的脚手架之外,我从未编写过生产型 Haskell 代码。我大致了解它——我将只写一个main
,在其中我将订阅消息队列,并在每条消息上进行我的标注/处理/存储——但我是否需要担心例如手动分叉确保在等待调用完成时进程不会阻塞?
非常感谢。