我有一个名为/ examples / 1 / duplicate的页面 在那里有一个ajax形式开始/ examples / 1 / run_duplicate
run_duplicate的控制器方法运行Example.duplicate(session) 我通过了会议,我理解这是一个神圣的禁忌。
重复的模型代码大致是:
def duplicate(session)
session[:duplicate] = 0
duplicate_foobars
session[:duplicate] = 1
duplicate_snafus
session[:duplicate] = 2
duplicate_widgets
session[:duplicate] = 3
end
我在重复页面上有另一个控制器方法正在进行长轮询:/ examples / 1 / check_dupe_status 目的是从会话[:重复]获取更新状态,调整进度报告, 并通过ajax将其报告给用户,以便他们可以看到Example.duplicate()的进度。
会议没有按照我希望的方式更新。我可以看到代码运行,但会话没有更新,所以/ examples / 1 / check_dupe_status永远不会知道任何事情已经开始。鉴于我从一开始就做错了,通知用户有关Example.duplicate()状态的正确方法是什么?
答案 0 :(得分:1)
听起来你有两个单独的请求,一个写入会话,一个尝试同时读取会话。那是对的吗?如果不是,请停止阅读。
这不起作用,因为“会话”只是一个cookie - HTTP响应的标题,作为cookie下载到您的浏览器,然后在下一个请求上重新上传,然后在下一个响应中重新下载, ad nosium。在您的代码中,这是操作的顺序:
/ examples / 1 / run_duplicate将“0”写入基本上是Ruby Hash的表示会话cookie
/ examples / 1 / check_dupe_status使用此请求从您的浏览器发送的会话cookie 中读取值。它可能根本没有任何内容:重复,因此它将显示为空白。
/ examples / 1 / run_duplicate将“1”写入Ruby会话哈希
/ examples / 1 / check_dupe_status再次读取该请求发送的会话cookie - 没有任何更改
/ examples / 1 / run_duplicate将“2”写入Ruby会话哈希
/ examples / 1 / check_dupe_status从最初发送的会话cookie中读取 - 无变化
/ examples / 1 / run_duplicate将“3”写入Ruby会话Hash 并且请求完成,将会话作为cookie返回,值为3:duplicate。< / p>
/ examples / 1 / check_dupe_status仍然像dufus一样坐在那里,阅读它最初发送的空白会话cookie
在某些时候,/ examples / 1 / check_dupe_status可能会超时,并且可能会返回会话cookie。但猜猜怎么了?因为:从未在那个会话cookie中设置了重复,它将覆盖浏览器中的重复,并且:在您发送的下一个请求中,重复将为空。
希望我能清楚地表达出来。基本上你在你的cookie中遇到竞争条件,如果你从同一个浏览器发送并发请求,这很难克服。
处理此问题的最佳方法是将重复的0,1,2等值写入某个数据库表。您的长轮询请求可能只是读出数据库。可能效率稍低,但当然它具有可以工作的优势。