问题:我需要控制由 foreach 循环并行处理任务的执行顺序。不幸的是,foreach 不支持这一点。
解决方案:使用 doRedis 使用数据库来保存在 foreach 循环中执行的所有任务。为了控制顺序,我想通过 setGetTask 覆盖 getTask 以根据预先指定的顺序获取任务。虽然我找不到太多关于如何做到这一点的文档。
附加信息:
在redis 文档中有一个关于 setGetTask 的小段落和一个示例 。
getTask <- function ( queue , job_id , ...) { key <- sprintf(" redisEval("local x=redis.call('hkeys',KEYS[1])[1]; if x==nil then return nil end; local ans=redis.call('hget',KEYS[1],x); redis.call('hdel',KEYS[1],x);i return ans",key) } setGetTask(getTask)
虽然我认为文档中的代码在语法上不正确(缺少恕我直言“和右括号”)“)。我认为这在 CRAN 上是不可能的,因为文档的代码是在提交时执行的。
更改 getTask 函数不会改变有关工人获取任务的任何内容(即使在 redisEval 中引入明显的废话,例如将其更改为 redisEval("dddddddddd(((")
从源代码安装软件包后,我只能访问 setGetTask 函数(我从1.1.1 版的官方 CRAN 软件包页面下载了该软件包(恕我直言,这与直接从 CRAN 安装它没有区别)
数据:要执行的任务的数据框如下所示:
taskName;taskQueuePosition;parameter1;paramterN
taskT;1;val1;10
taskK;2;val2;8
taskP;3;val3;7
taskA;4;val4;7
我想使用'taskQueuePosition'来控制顺序,应该先执行编号较小的任务。
问题:
- 有人知道我可以从哪里获得有关使用 doRedis 或 setGetTask 执行此操作的更多信息的任何来源吗?
- 有人知道我需要如何更改 getTask 以实现上述目的吗?
- 还有其他聪明的想法来控制 foreach 循环中的执行顺序吗?最好是这样在某些时候我可以使用 doRedis 作为并行后端(更改这将意味着由于复杂的技术基础设施原因而对处理进行重大更改)。
代码(便于复制):
下面假设redis-server在本地机器上启动。
Redis 数据库填充:
library(doRedis)
library(foreach)
options('redis:num'=TRUE) # needed for proper execution
REDIS_JOB_QUEUE = "jobs"
registerDoRedis(REDIS_JOB_QUEUE)
# filling up the data frame
taskDF = data.frame(taskName=c("taskT","taskK","taskP","taskA"),
taskQueuePosition=c(1,2,3,4),
parameter1=c("val1","val2","val3","val4"),
parameterN=c(10,8,7,7))
foreach(currTask=iter(taskDF, by='row'),
.verbose = T
) %dopar% {
print(paste("Executing task: ",currTask$taskName))
Sys.sleep(currTask$parameterN)
}
removeQueue(REDIS_JOB_QUEUE)
工人:
library(doRedis)
REDIS_JOB_QUEUE = "jobs"
startLocalWorkers(n=1, queue=REDIS_JOB_QUEUE)