简单轮询结果文件的实现
Posted
技术标签:
【中文标题】简单轮询结果文件的实现【英文标题】:Implementation of simple polling of results file 【发布时间】:2014-05-07 12:40:09 【问题描述】:对于我论文的一个数据收集模块,我实现了一个简单的轮询机制。这是必需的,因为我将每个数据收集请求(许多请求之一)作为 SQL 查询,通过 Web 表单提交,由 RCurl 代码模拟。服务器处理每个请求并在特定 URL 处生成带有结果的文本文件(下面的代码中的RESULTS_URL
)。无论请求如何,URL 和文件名都是相同的(我无法更改)。由于不同数据请求的处理时间显然不同,并且某些请求可能需要大量时间,我的R
代码需要“知道”,当结果准备好(重新生成文件)时,它可以取回它们。以下是我对这个问题的解决方案。
POLL_TIME <- 5 # polling timeout in seconds
在函数srdaRequestData()
中,在进行数据请求之前:
# check and save 'last modified' date and time of the results file
# before submitting data request, to compare with the same after one
# for simple polling of results file in srdaGetData() function
beforeDate <- url.exists(RESULTS_URL, .header=TRUE)["Last-Modified"]
beforeDate <<- strptime(beforeDate, "%a, %d %b %Y %X", tz="GMT")
<making data request is here>
在函数srdaGetData()
中,在srdaRequestData()
之后调用
# simple polling of the results file
repeat
if (DEBUG) message("Waiting for results ...", appendLF = FALSE)
afterDate <- url.exists(RESULTS_URL, .header=TRUE)["Last-Modified"]
afterDate <- strptime(afterDate, "%a, %d %b %Y %X", tz="GMT")
delta <- difftime(afterDate, beforeDate, units = "secs")
if (as.numeric(delta) != 0) # file modified, results are ready
if (DEBUG) message(" Ready!")
break
else # no results yet, wait the timeout and check again
if (DEBUG) message(".", appendLF = FALSE)
Sys.sleep(POLL_TIME)
<retrieving request's results is here>
模块的主要事件流/顺序是线性的,如下:
Read/update configuration file
Authenticate with the system
Loop through data requests, specified in configuration file (via lapply()),
where for each request perform the following:
...
Make request: srdaRequestData()
...
Retrieve results: srdaGetData()
...
上面代码的问题是它似乎没有按预期工作:在发出数据请求时,代码应该打印“Waiting for results . .." 然后,定期检查结果文件是否被修改(重新生成),打印进度点,直到结果准备好,当它打印确认时。然而,实际行为是代码等待很长时间(我故意让一个请求长时间运行),不打印任何内容,但随后显然检索结果并打印“Waiting for results ...”和“Ready”同时。
在我看来这是某种同步问题,但我无法弄清楚究竟是什么。或者,也许它是其他东西,我不知何故错过了它。 我们将不胜感激您的建议和帮助!
【问题讨论】:
消息可能正在缓冲。也许它们一生成就不会写到屏幕上。但是由于我无法运行代码并对其进行测试,所以很难说。如果所有文件都很好并且只有消息是备份的,那么这似乎是最有可能的情况。有时发送\n
可能会触发缓冲区刷新。
@MrFlick:有趣,我还没考虑过输出的缓冲!你是对的,再一次!结果似乎很好,只是显示进度与现实不符。但是,现在没关系 - 我有太多其他 - 更重要的 - 需要担心的事情...... :-)。非常感谢您的帮助!
【参考方案1】:
在对该问题的评论中,我相信 MrFlick
解决了这个问题:轮询逻辑似乎可以正常工作,但 问题是进度消息与 不同步系统上的当前事件。
默认情况下,R 控制台输出是缓冲的。这是设计使然:加快速度并避免可能与频繁消息等相关的令人分心的闪烁。我们往往会忘记这个事实,尤其是在我们以非常互动的方式使用 R 并运行各种临时语句之后在控制台(在返回 >
提示符之前,控制台缓冲区会自动刷新)。
然而,可以通过在每个关键输出语句之后显式刷新控制台、使用 flush.console()
函数或通过在R GUI(在控制台上右键单击,请参阅Buffered output Ctrl W
项目。这也可在Misc
菜单中使用)
这是一个显式使用 flush.console 的玩具示例。请注意使用cat()
而不是message()
,因为前者不会自动将CR/LF 添加到输出中。然而,后者很有用,因为它的消息可以用suppressMessages()
等来抑制。同样如评论中所示,您可以使用“\b”(退格)字符使数字相互覆盖。
CountDown <- function()
for (i in 9:1)
cat(i)
# alternatively to cat(i) use: message(i)
flush.console() # <<<<<<< immediate ouput to console.
Sys.sleep(1)
cat(" ") # also try cat("\b") instead ;-)
cat("... Blast-off\n")
输出如下,在这个打印输出中当然不明显的是,在最后的“Blast off”之前,总共花了 10 秒,每秒打印一个数字;删除 flush.console() 语句,输出将在 10 秒后立即出现,即当函数终止时(除非控制台没有在 GUI 级别缓冲)。
倒计时() 9 8 7 6 5 4 3 2 1 ... 爆炸
【讨论】:
很棒的答案!谢谢一百万!以上是关于简单轮询结果文件的实现的主要内容,如果未能解决你的问题,请参考以下文章