You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

任务计划程序无法自动刷新过期OAuth令牌问题排查

Dropbox自动上传脚本在任务计划程序中4小时后冻结问题排查与解决

问题详情

  • 使用R的rdrop2包实现Dropbox自动上传持续更新的文件,本地RStudio运行完全正常
  • 通过Windows任务计划程序执行Rscript.exe运行脚本时,前4小时正常,之后任务会"冻结"(持续显示"运行"状态但停止上传)
  • 手动结束并重启任务可恢复正常,但4小时后会重复出现相同问题
  • 日志曾提示"Auto-refreshing stale OAuth token",移除sink日志后问题依旧,推测与OAuth可刷新令牌的刷新逻辑有关
  • 已将Rscript.exe路径添加至系统PATH,任务执行模式为调用Rscript传入脚本

现有脚本

library(rdrop2)
library(httr)
library(dplyr)

setwd("C:/Users/benke/Documents/R Main Directory/Data Upload Automation")

error_log <- file("C:/Users/benke/Documents/R Main Directory/Data Upload Automation/error_log.Rout", 
                  open = "wt")

sink(error_log, type = "message")

#Set up refreshable access token, can pass this to any 'drop' function in 'dtoken' argument
.dstate <- new.env(parent = emptyenv())

drop_auth_RT <- function (new_user = FALSE, key = "placeholder", secret = "placeholder", cache = TRUE, rdstoken = NA) 
{
  if (new_user == FALSE & !is.na(rdstoken)) {
    if (file.exists(rdstoken)) {
      .dstate$token <- readRDS(rdstoken)
    }
    else {
      stop("token file not found")
    }
  }
  else {
    if (new_user && file.exists(".httr-oauth")) {
      message("Removing old credentials...")
      file.remove(".httr-oauth")
    }
    dropbox <- httr::oauth_endpoint(authorize = "https://www.dropbox.com/oauth2/authorize?token_access_type=offline",
                                    access = "https://api.dropbox.com/oauth2/token")
    # added "?token_access_type=offline" to the "authorize" parameter so that it can return an access token as well as a refresh token
    dropbox_app <- httr::oauth_app("dropbox", key, secret)
    dropbox_token <- httr::oauth2.0_token(dropbox, dropbox_app, 
                                          cache = cache)
    if (!inherits(dropbox_token, "Token2.0")) {
      stop("something went wrong, try again")
    }
    .dstate$token <- dropbox_token
  }
}

refreshable_token <- drop_auth_RT()

#Upload updated copy of file
drop_upload(file = "biostats.csv", path = "/auto_test",
            mode = "overwrite",
            dtoken = refreshable_token)

解决方案建议

1. 为OAuth请求添加超时限制

非交互环境(如任务计划程序)中,无响应的网络请求会导致脚本卡住。在令牌获取/刷新时显式设置超时:

# 修改oauth2.0_token调用,添加30秒超时
dropbox_token <- httr::oauth2.0_token(dropbox, dropbox_app, 
                                      cache = cache,
                                      config = httr::timeout(30))
# 同时给drop_upload也添加超时
drop_upload(file = "biostats.csv", path = "/auto_test",
            mode = "overwrite",
            dtoken = refreshable_token,
            config = httr::timeout(30))

2. 显式管理令牌缓存,避免依赖内部环境

原脚本中使用.dstate内部环境存储令牌,在非交互模式下可能存在上下文丢失问题,改为显式保存/加载令牌文件:

# 修改drop_auth_RT函数,显式保存令牌
drop_auth_RT <- function (new_user = FALSE, key = "placeholder", secret = "placeholder", cache_path = "dropbox_token.rds") 
{
  if (!new_user && file.exists(cache_path)) {
    token <- readRDS(cache_path)
    # 检查令牌是否即将过期,提前刷新
    if (httr::token_expiry(token) < Sys.time() + 300) {
      token <- httr::oauth2.0_refresh(token)
      saveRDS(token, cache_path)
    }
    return(token)
  } else {
    # 原有授权逻辑...
    dropbox <- httr::oauth_endpoint(authorize = "https://www.dropbox.com/oauth2/authorize?token_access_type=offline",
                                    access = "https://api.dropbox.com/oauth2/token")
    dropbox_app <- httr::oauth_app("dropbox", key, secret)
    dropbox_token <- httr::oauth2.0_token(dropbox, dropbox_app, 
                                          cache = FALSE) # 关闭默认缓存,用自定义文件
    saveRDS(dropbox_token, cache_path)
    return(dropbox_token)
  }
}

# 调用时加载令牌
refreshable_token <- drop_auth_RT()

3. 改为单次执行+定时触发,避免长会话

不要让脚本持续运行4小时,改为任务计划程序每15-60分钟执行一次单次上传脚本:

  • 移除脚本中可能存在的循环逻辑(如果有的话)
  • 任务计划程序设置为"按预定计划"执行,时间间隔根据文件更新频率调整
  • 每次执行都是全新的R会话,彻底避免令牌刷新时的长连接问题

4. 增强日志调试,定位卡住环节

恢复sink日志,但添加更多调试信息,记录令牌状态和上传步骤:

# 在令牌获取后添加日志
refreshable_token <- drop_auth_RT()
cat(paste0("Token loaded, expiry time: ", httr::token_expiry(refreshable_token), "\n"), file = "debug.log", append = TRUE)

# 上传前后添加日志
cat(paste0("Starting upload at: ", Sys.time(), "\n"), file = "debug.log", append = TRUE)
upload_result <- drop_upload(file = "biostats.csv", path = "/auto_test",
            mode = "overwrite",
            dtoken = refreshable_token)
cat(paste0("Upload completed at: ", Sys.time(), " Result: ", upload_result$name, "\n"), file = "debug.log", append = TRUE)

5. 更新依赖包到最新版本

旧版本的rdrop2或httr可能存在OAuth刷新的bug,执行以下命令更新:

install.packages(c("rdrop2", "httr"))

内容的提问来源于stack exchange,提问作者bkelley9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:32:33