繁体   English   中英

如何在 R HTTPUV startServer 中实现异步调用?

[英]How to implement async calls in R HTTPUV startServer?

R httpuv startServer function 应该在 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
        )
      )

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

# 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)

                # Respond with HTTP 200 OK
                list(
                    status = 200,
                    body = "Slept for 5 seconds",
                    headers = list(
                        # Content-Type is important, otherwise you will run
                        # into a "not compatible with STRSXP" error.
                        "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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM