【问题标题】:How to implement async calls in R HTTPUV startServer?如何在 R HTTPUV startServer 中实现异步调用?
【发布时间】:2022-08-18 22:28:53
【问题描述】:

R httpuv startServer 函数应该在 app 参数的调用部分支持异步处理,但我无法让它工作。有谁知道如何做到这一点?下面的示例不起作用,但它显示了我正在尝试执行的操作,异步运行每个请求(或特定页面),以便在另一个请求正在处理时加载页面。

startServer(
        host,
        port,
        app = list(
          call = function(req) {
            req <- list(
              \"REQUEST_METHOD\" = req$REQUEST_METHOD,
              \"SCRIPT_NAME\" = req$SCRIPT_NAME,
              \"PATH_INFO\" = req$PATH_INFO,
              \"QUERY_STRING\" = req$QUERY_STRING,
              \"SERVER_NAME\" = req$SERVER_NAME,
              \"SERVER_PORT\" = req$SERVER_PORT,
              \"HEADERS\" = req$HEADERS,
              \"rook.input\" = req[[\"rook.input\"]]$read_lines()
            )

            future_promise({
              if(req$PATH_INFO %in% valid_dynamic_paths){

                x <- eval(dynamic[[req$PATH_INFO]][req$REQUEST_METHOD])

                list(
                  status = x[[\"status\"]],
                  headers = x[[\"headers\"]],
                  body = x[[\"body\"]]
                )

              }else{

                list(
                  status = 404,
                  headers = list(
                    \'Content-Type\' = \'text/html\'
                  ),
                  body = \"404. Page not found.\"
                )

              }
            })
          },
          staticPaths = static
        )
      )
  • 你能找到解决这个问题的方法吗?我看到(假设)您的Github issue 已完成关闭。

标签: r shiny httpuv


【解决方案1】:

我能够得到类似于工作的东西。下面的代码显示了它的要点:

# fork a process for each new request
future::plan(future::multicore)

httpuv::runServer("0.0.0.0", 8080, list(
    call = function(req) {
        # `as.promise` is necessary, because `httpuv` is using `is.promise`
        # under the hood to act differently. Unfortunately `is.promise` returns
        # `FALSE` for a `future`.
        promises::as.promise(
            future::future({
                Sys.sleep(5)
                list(
                    status = 200,
                    body = "Slept for 5 seconds",
                    headers = list(
                        "content-type" = "text/plain"
                    )
                )
            })
        )
    }
))

在(几乎)同时调用服务器请求,将表明您只等待两个请求的 5 秒,而不是一个等待 5 秒,另一个等待 10 秒。

time curl -s localhost:8080 > /dev/null &
time curl -s localhost:8080 > /dev/null 

# After 5 seconds you should see output similar to the following:

# real    0m5.089s
# user    0m0.011s
# sys     0m0.010s

# real    0m5.112s
# user    0m0.020s
# sys     0m0.024s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2018-03-14
    • 2011-08-03
    • 2012-08-30
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多