Создание очереди с помощью Firestore просто и идеально подходит для вашего случая использования. Идея состоит в том, чтобы записать задачи в коллекцию queue со сроком выполнения, который затем будет обработан при наступлении срока.
Вот пример.
- Каждый раз, когда происходит ваше начальное событие
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
});
Использование такой очереди также делает вашу систему более надежной - если что-то пойдет не так, вы не потеряете задачи, которые каким-то образом могли бы существовать в памяти, но до тех пор, пока они не помечены как обработанные, fixed worker возьмет их и повторно обработает. Это, конечно, зависит от вашей реализации.