简单轮询结果文件的实现

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 并运行各种临时语句之后在控制台(在返回 &gt; 提示符之前,控制台缓冲区会自动刷新)。

然而,可以通过在每个关键输出语句之后显式刷新控制台、使用 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 ... 爆炸

【讨论】:

很棒的答案!谢谢一百万!

以上是关于简单轮询结果文件的实现的主要内容,如果未能解决你的问题,请参考以下文章

基于HTTP的长轮询简单实现

使用 sqlplus 轮询并将结果记录到文件中强制换行

实现一个简单的加权轮询算法

使用 Spring 集成轮询 S3 存储桶以获取文件

轮询直到得到具体结果?

如何实现基本的“长轮询”?