理解Promises包中异步任务的阻塞执行问题

理解Promises包中异步任务的阻塞执行问题

promises A promise library for R promises 项目地址: https://gitcode.com/gh_mirrors/prom/promises

背景介绍

在R语言的异步编程中,promises包是一个强大的工具,它允许开发者以更优雅的方式处理异步操作。然而,当我们在非交互式环境中(如Rscript或R -e命令)使用promises时,可能会遇到一个常见问题:异步任务未能按预期执行完成。

问题现象

当使用promises包中的promise_all函数组合多个异步任务时,在交互式R会话中能够正常工作,但在非交互式环境下(如通过Rscript执行)会出现异步任务未完成就被终止的情况。这是因为R进程在函数执行完毕后立即退出,而不会等待异步任务完成。

解决方案

为了解决这个问题,我们需要一种机制来阻塞主进程,直到所有异步任务完成。以下是实现这一目标的几种方法:

基本阻塞实现

block_until_settled <- function(p) {
  promise_resolved <- FALSE
  p$finally(function(value) {
    promise_resolved <<- TRUE
  })
  
  while(!promise_resolved) {
    later::run_now(1)
  }
}

这个函数通过不断检查promise状态来实现阻塞,直到promise被解决(resolved)或拒绝(rejected)。

带超时机制的阻塞实现

为了防止无限等待,我们可以添加超时机制:

block_until_settled <- function(p, timeout = 10) {
  start_time <- as.numeric(Sys.time())
  promise_resolved <- FALSE
  p$finally(function(value) {
    promise_resolved <<- TRUE
  })
  
  while(!promise_resolved) {
    if (Sys.time() > start_time + timeout) {
      stop("Timed out!")
    }
    later::run_now(0.5)
  }
}

这种实现方式在超时后会抛出错误,但需要注意在交互式会话中,即使超时,异步任务仍会在后台继续执行。

使用示例

以下是一个完整的使用示例,展示了如何结合future_promise和阻塞机制:

buildDB_sarek <- function() {
  library(future)
  library(promises)
  
  # 创建多个异步任务
  csq_promise <- future_promise({
    csq.vcf <- data.frame("a" = "a")
    message("执行csq_promise任务")
    return(csq.vcf)
  })
  
  info_promise <- future_promise({
    info.vcf <- data.frame("a" = "a")
    message("执行info_promise任务")
    return(info.vcf)
  })
  
  # 组合多个promise
  combined_promise <- promise_all(geno_promise, csq_promise, info_promise) %...>% {
    # 处理结果
    message("所有任务完成")
  }
  
  # 阻塞直到所有任务完成
  block_until_settled(combined_promise)
}

注意事项

  1. 避免在Shiny或Plumber应用中使用:这种阻塞机制会干扰这些框架的事件循环机制,可能导致不可预知的行为。

  2. 集群环境考虑:在集群环境中使用时要特别注意资源管理,确保不会因为阻塞导致资源浪费。

  3. 性能影响:频繁检查promise状态会带来一定的性能开销,应根据实际情况调整检查间隔。

总结

通过实现阻塞机制,我们可以在非交互式环境中确保异步任务完成后再退出进程。这种方法特别适用于脚本执行、批处理作业等场景。然而,开发者需要根据具体应用场景权衡使用,并注意相关的限制和注意事项。

理解promises包的这种特性有助于我们更好地设计异步程序,特别是在需要将交互式开发成果部署到生产环境时,能够避免因执行环境差异导致的问题。

promises A promise library for R promises 项目地址: https://gitcode.com/gh_mirrors/prom/promises

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢辰鹰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值