我试图构建一个加密撤销系统,并且需要确保系统不会重复等等,所以我决定使用Agenda来帮助我。我遇到的问题是我需要监听作业的完成情况,以便从新发送的事务中检索事务ID。这只有在作业完成后才可用,我找不到任何关于使用听众进行一项工作的事情。
以下是我的代码的一部分:
let pendingUserWithdrawJob = await Job.count({ name: "withdraw_order", "data.userId": user._id, completed: { $ne: true } });
if (pendingUserWithdrawJob > 0) return 1;
const job = global.agenda.create('withdraw_order', {userId: user._id, recipientAddress: addr, amount, txid: null });
job.save((err) => {
if (err) return false;
return msg.reply('Successfully withdrawn! TXID: ' + job.attrs.data.txid);
});
这是在任何类型的检查完成之前,并且txid返回null,这是预期的。
这是我的议程定义代码:
agenda.define('withdraw_order', async function(job, done) {
let result = await paymentProcessor.performWithdraw(job);
if (result.error) return done(result.error);
done();
});
有问题的performWithdraw函数是:
async performWithdraw(options) {
try {
await this.withdraw(options);
return { success: true };
} catch(e) {
this.reportException(e);
return { error: e };
}
}
this.withdraw:
async withdraw(job) {
// parameters
const userId = job.attrs.data.userId;
const recipientAddress = job.attrs.data.recipientAddress;
const amount = job.attrs.data.amount;
// Validate if user is present
let user = await models.User.findById(userId);
if (!user) throw new Error(`User ${userId} not found`);
await models.User.validateWithdrawAmount(user, amount);
// Step 1: Process transaction
let sendID;
if (job.attrs.sendStepCompleted) {
sendID = job.attrs.txid;
} else {
const sent = await this.pivxClient.send(recipientAddress, amount);
if (sent.error) throw new Error(sent.error);
await models.Job.findOneAndUpdate({ _id: job.attrs._id} , { "data.sendStepCompleted": true, "data.txid": sent.txid });
}
// Step 2: Update user balance
if (!job.attrs.userStepCompleted) {
await models.User.withdraw(user, amount);
await models.Job.findByIdAndUpdate(job.attrs._id, { "data.userStepCompleted": true });
}
// Step 3: Record Transaction
if (!job.attrs.transactionStepCompleted) {
await models.Transaction.create({ userId: userId, withdraw: amount, txid: sendID });
await models.Job.findByIdAndUpdate(job.attrs._id, { "data.transactionStepCompleted": true });
}
return sendID;
}
提前为代码混乱道歉,我只是想确保我没有留下任何可能重要的东西。如何在不使用setInterval并检查transactionStepCompleted的情况下监听要完成的工作?
答案 0 :(得分:0)
一个议程实例将发出以下事件:
开始-在工作开始之前调用
开始:工作名称-在指定工作开始之前调用
complete-完成作业时调用,而不管它是成功还是失败
complete:job name-作业完成时调用,无论其成功与否
agenda.on('start', job => {
console.log('Job %s starting', job.attrs.name);
});
agenda.on('complete', job => {
console.log(`Job ${job.attrs.name} finished`);
});