我在 App Engine 上有一个应用程序正在消耗一些数据。在解析了这些数据之后,它会知道它需要在一段时间内执行某些事情——可能不需要几个小时或几周。
在 App Engine 上任意时间后执行一段代码的最佳方法是什么?
我认为使用TaskQueue 中的Countdown Millis或EtaMillis会起作用,但没有看到任何证据表明有人在做同样的事情,尤其是在这么长的时间范围内。
这是最好的方法,还是有更好的方法?
我在 App Engine 上有一个应用程序正在消耗一些数据。在解析了这些数据之后,它会知道它需要在一段时间内执行某些事情——可能不需要几个小时或几周。
在 App Engine 上任意时间后执行一段代码的最佳方法是什么?
我认为使用TaskQueue 中的Countdown Millis或EtaMillis会起作用,但没有看到任何证据表明有人在做同样的事情,尤其是在这么长的时间范围内。
这是最好的方法,还是有更好的方法?
如果您能够将包含所有相关信息的对象保存在数据存储中以供将来处理(包括何时开始处理对象数据),则可以让 cron 作业定期使用日期/时间范围过滤器查询数据存储并在适当的时候触发处理上述任何对象。
我们成功使用 TaskQueue 的倒计时参数在客户注册 7 天后向客户发送电子邮件以及满足其他需求。
任务队列是核心/基本 API/服务,并且非常可靠 - 我认为这是使用任务队列 ETA/倒计时的最佳方式,除非您:
我将任务队列用作调度程序。在QueueConstants中声明并在QueueImpl中应用了 30 天的 max eta 。
//Returns the maximum time into the future that a task may be scheduled.
private static final long MAX_ETA_DELTA_MILLIS = 2592000000L;
1000 毫秒 * 60 秒 * 60 米 * 24 小时 * 30 天 = 2592000000 毫秒
private long determineEta(TaskOptions taskOptions) {
Long etaMillis = taskOptions.getEtaMillis();
Long countdownMillis = taskOptions.getCountdownMillis();
if (etaMillis == null) {
if (countdownMillis == null) {
return currentTimeMillis();
} else {
if (countdownMillis > QueueConstants.getMaxEtaDeltaMillis()) {
throw new IllegalArgumentException("ETA too far into the future");
}
if (countdownMillis < 0) {
throw new IllegalArgumentException("Negative countdown is not allowed");
}
return currentTimeMillis() + countdownMillis;
}
} else {
if (countdownMillis == null) {
if (etaMillis - currentTimeMillis() > QueueConstants.getMaxEtaDeltaMillis()) {
throw new IllegalArgumentException("ETA too far into the future");
}
if (etaMillis < 0) {
throw new IllegalArgumentException("Negative ETA is invalid");
}
return etaMillis;
} else {
throw new IllegalArgumentException(
"Only one or neither of EtaMillis and CountdownMillis may be specified");
}
}
}
我执行以下操作:
将具有您提到的延迟配置的任务排入队列。让任务处理以已知方式更改数据存储条目(例如:设置标志)。
有一个落后的低频 cron 作业,以执行任何被排队任务以某种方式遗漏的处理(例如:任务中发生未捕获的异常)。
为此,请确保任务和 cron 作业调用的处理是幂等的。
享受?
我认为 taskQueue 是一个很好的策略,但有一个大问题“如果一个推送任务创建成功,它最终会被删除(最多在任务成功执行后 7 天)。” 资源
我会改为使用datastore。这是您可以采取的一种策略:
以下是如何将记录添加到数据存储......让你开始......
Entity parsDataHolder = new Entity("parsing_data_done", guestbookKey);
parsDataHolder.setProperty("date", date);
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(parsDataHolder)