我遇到了一个棘手的问题。
我正在迭代一组按日期参数化的URL并获取它们。例如,以下是一个示例:
somewebservice.com?start=01-01-2012&end=01-10-2012
有时,从URL返回的内容会被截断(缺少附加'截断错误'消息的随机结果),因为我已经定义了太大的范围,所以我必须将查询拆分为两个URL
somewebservice.com?start=01-01-2012&end=01-05-2012
somewebservice.com?start=01-06-2012&end=01-10-2012
我递归执行此操作,直到结果不再被截断,然后我写入一个允许并发写入的blob。
这些URL提取调用/ blob写入中的每一个都在单独的任务队列任务中处理。
问题是,我不能为我的生活设计一个方案来了解所有任务何时完成。我尝试过使用分片计数器,但递归使得它变得困难。有人建议我使用Pipeline API,所以我看了3次Slatkin谈话。它似乎不适用于递归(但我承认我仍然不完全理解lib)。
反正知道什么时候完成一组任务队列任务(以及递归生成的子项),所以我可以完成我的blob并用它做任何事情?
谢谢, 约翰
答案 0 :(得分:2)
您是否阅读过Pipelines Getting Started个文档?管道可以创建其他管道并等待它们,所以做你想要的是相当简单的:
class RecursivePipeline(pipeline.Pipeline):
def run(self, param):
if some_condition: # Too big to process in one
p1 = yield RecursivePipeline(param1)
p2 = yield RecursivePipeline(param2)
yield RecursiveCombiningPipeline(p1, p2)
其中RecursiveCombiningPipeline
只是作为两个子管道值的接收器。
答案 1 :(得分:0)
好的,所以这就是我的所作所为。我不得不稍微修改Mitch的解决方案,但他确实让我朝着正确的方向前进,提出了返回未来价值的建议而不是直接的价值。
我必须创建一个intermidate DummyJob,它接受递归的输出
public static class DummyJob extends Job1<Void, List<Void>> {
@Override
public Value<Void> run(List<Void> dummies) {
return null;
}
}
然后,我将DummyJob的输出提交给waitFor
中的Blob FinalizerList<FutureValue<Void>> dummies = new ArrayList<FutureValue<Void>>();
for (Interval in : ins) {
dummies.add(futureCall(new DataFetcher(), immediate(file), immediate(in.getStart()),
immediate(in.getEnd())));
}
FutureValue<Void> fv = futureCall(new DummyJob(), futureList(dummies));
return futureCall(new DataWriter(), immediate(file), waitFor(fv));
谢谢Mitch和Nick !!