我想要一个cron作业/调度程序,它将在Firestore中发生onCreate事件后每30分钟运行一次。cron作业应该触发一个云函数,该函数拾取在过去30分钟内创建的文档,并根据json模式验证它们,并将它们保存在另一个集合中。如何通过编程编写这样一个调度程序来实现这一点?什么也是故障安全机制,以及在运行cron作业之前对创建的文档进行某种排队/跟踪,以将它们推送到另一个集合。
使用Firestore构建队列非常简单,非常适合您的用例。其想法是将任务写入队列集合,并指定到期日期,然后在到期时对其进行处理。
下面是一个例子。
- 每当集合的初始
onCreate
事件发生时,请将包含以下数据的文档写入tasks
集合:
duedate: new Date() + 30 minutes
type: 'yourjob'
status: 'scheduled'
data: '...' // <-- put whatever data here you need to know when processing the task
- 让员工定期拿起可用的工作——例如,根据您的需要,每分钟一次
// Define what happens on what task type
const workers: Workers = {
yourjob: (data) => db.collection('xyz').add({ foo: data }),
}
// The following needs to be scheduled
export const checkQueue = functions.https.onRequest(async (req, res) => {
// Consistent timestamp
const now = admin.firestore.Timestamp.now();
// Check which tasks are due
const query = db.collection('tasks').where('duedate', '<=', new Date()).where('status', '==', 'scheduled');
const tasks = await query.get();
// Process tasks and mark it in queue as done
tasks.forEach(snapshot => {
const { type, data } = snapshot.data();
console.info('Executing job for task ' + JSON.stringify(type) + ' with data ' + JSON.stringify(data));
const job = workers[type](data)
// Update task doc with status or error
.then(() => snapshot.ref.update({ status: 'complete' }))
.catch((err) => {
console.error('Error when executing worker', err);
return snapshot.ref.update({ status: 'error' });
});
jobs.push(job);
});
return Promise.all(jobs).then(() => {
res.send('ok');
return true;
}).catch((onError) => {
console.error('Error', onError);
});
});
如果有任务到期,您有不同的选项来触发队列检查:
- 使用http可调用函数,如上例所示。这需要您定期对此函数执行http调用,以便它执行并检查是否有任务要完成。根据您的需要,您可以从自己的服务器或使用cron-job.org等服务来执行调用请注意,HTTP可调用函数将公开可用,其他人也可以调用它。但是,如果您使检查代码为幂等,这应该不是问题
- 使用Firebase";内部";cron选项,该选项在内部使用Cloud Scheduler。使用它可以直接触发队列检查:
export scheduledFunctionCrontab =
functions.pubsub.schedule('* * * * *').onRun((context) => {
console.log('This will be run every minute!');
// Include code from checkQueue here from above
});
使用这样的队列还可以使您的系统更加健壮-如果在这两者之间出现问题,您将不会丢失只存在于内存中的任务,但只要它们没有标记为已处理,修复的工作人员就会将它们取起来并重新处理。这当然取决于您的实现。
您可以在Firestore Create事件上触发一个云函数,该函数将在30分钟后安排云任务。这将具有排队和重试机制。
一个简单的方法是,您可以添加一个带有时间戳的created
字段,然后让一个计划函数在预定义的时间段(例如,每分钟一次(运行,并为created >= NOW - 31 mins AND created <= NOW - 30 mins
(伪代码(所在的所有记录执行特定代码。如果您的时间精度要求不是很高,那么在大多数情况下都应该适用。
如果这不适合您的需求,您可以添加云任务(谷歌云产品(。这篇好文章详细说明了细节。