ambiorix-web / ambiorix

🖥️ Web framework for R
http://ambiorix.dev
GNU General Public License v3.0
211 stars 9 forks source link

How to handle non-blocking async operations with coro in ambiorix? #74

Open spirae-nevin opened 3 days ago

spirae-nevin commented 3 days ago

Problem : I'm trying to make a long running task non blocking using async from coro in ambiorix but still getting blocked / delayed even though the function is asynchronously declared.

Goal : To let the server handle other requests in the meantime.

Reproducible Example :
app.R

box::use(
  . / router[router],
)

box::use(
  ambiorix[Ambiorix]
)

app <- Ambiorix$new()
app$use(router)

app$start(port = 2050, host = "127.0.0.1")

router.R

box::use(
  ambiorix[Router]
)

box::use(
  . / controller[servePingInfo, serveLongRunningTask]
)

#' @export
router <- Router$new("/")

router$get("/ping", servePingInfo)
router$get("/long-task", serveLongRunningTask)

controller.R

box::use(
  ambiorix[Router],
  coro[async]
)

#' @export
servePingInfo <- async(function(req, res) {
  status <- "sucess"
  res$json(status)
})

#' @export
serveLongRunningTask <- async(function(req, res) {
  Sys.sleep(10)
  status <- "YOur wait is over"
  res$json(status)
})

Current Behavior : When hitting the /long-task endpoint, the server blocks for 10 seconds due to Sys.sleep(10) before responding. During this time, no other requests can be handled.

Note : It would be helpful if asynchronous approach can be done using coro libraries as it looks more similar to JavaScript. Main thing to notice is that I'm not using await(). I cannot use await here like this router$get("/ping", await(servePingInfo)). This throws an error

jrosell commented 3 days ago

I have though a little for async in ambiorix too. I think it's worth exploring similar approach as ExtendedTask + furure/mirai. Correct me if i'm wrong @JohnCoene, I think the current approach is using belgic.

JohnCoene commented 3 days ago

The way we have async is just using future, see here, we can consider support for coro, i just need to understand the library a bit more to know what needs adapting in Ambiorix.

Belgic is a vertical load balancer for ambiorix, similar to shiny server.