我遇到了一个特定的问题并想到了一个解决方案。但由于解决方案非常复杂,我想知道其他人是否遇到过类似的问题,并且可以评论最佳做法或提出替代方案。
问题如下: 我有一个用Django编写的webapp,它有一些屏幕,其中来自多个表的数据以时间间隔被收集,分组和聚合。 它基本上是一个很好的矩阵,我们在一个轴上以时间间隔汇总数据,而另一个轴上每个时间间隔的聚合数据资源。 它涉及许多内部和左侧连接以收集所有数据,并且由于“报告”类似于所呈现数据的特征,我使用原始sql一起查询所有内容。
问题是多个用户可以同时查看&以这些间隔编辑数据。与使用相同数据但处于子/重叠间隔的其他用户相比,他们还可以编辑更精细或更粗粒度的数据。目前,当用户编辑某些数据时,会触发django请求,更改数据,聚合受影响的间隔。再次分组并呈现回来。但是由于这些数据的易变性,其他用户可能在他们面前改变了一些东西。每次分组/聚合和重新呈现表是非常繁重的操作(取决于数据量和间隔的范围)。并发用户编辑时会变得更糟..
我建议的解决方案: 很明显,http请求/响应机制对于这种事情并不是很理想;分组/聚合是非常重要的,对于每个请求来说并不理想,并发性最好是在用户之间传递,反馈应该是实时的,如googledocs而不是整页刷新。
我正在考虑制作一个守护程序进程,该进程根据请求从dbms读取感兴趣的 flat 数据并将其缓存在内存中。然后,对数据的所有更改都将在内存中进行,并对dbms进行直写。此守护程序通过锁定通道访问数据,因此守护程序可以处理哪些用户可以覆盖其他更改。
使用python代码聚合和分组平面数据,并且仅返回用户所需的切片;用户/守护进程通信将在websockets上运行。守护程序将提供订阅者/发布者通道,其中对特定数据片段感兴趣的用户在发生更改时得到通知。这个守护进程可以使用像twisted这样的框架来实现。但是我不确定事件驱动的方法在这里会起作用,因为我们想要“引导”所有的请求......也许这些应该放在一个队列中并在一个单独的线程中运行?在我的调度程序旁边的线程中进行扭曲运行会更好吗,或者扭曲的主循环是否应该关闭在此队列上运行的线程?我的理解是,线程最适合IO,而python重码基本上阻止了其他线程。我有两个(websockets / dbms和处理数据),这会起作用吗?
以前有人做过类似的事吗?
提前致谢!
卡尔
答案 0 :(得分:3)
Google针对现已放弃的Wave产品的并发编辑功能实施的方案已记录在案http://www.waveprotocol.org/whitepapers/operational-transform。 Wave的这个方面似乎是成功的,尽管Wave本身很快就被抛弃了。
就您提出的有关实施拟议方案的问题而言:
答案 1 :(得分:2)
我尝试了类似的东西,你可能对解决方案感兴趣。这是我的问题:
python Socket.IO client for sending broadcast messages to TornadIO2 server
这就是答案:
https://stackoverflow.com/a/10950702/675065
他还写了一篇关于解决方案的博客文章:
http://blog.y3xz.com/blog/2012/06/08/a-modern-python-stack-for-a-real-time-web-application/
软件堆栈包括:
我自己实现了它,它就像一个魅力。