У меня есть две функции, scheduleScan()
и scan()
.
scan()
звонки, scheduleScan()
когда больше ничего не нужно делать, кроме планирования нового сканирования , поэтому scheduleScan()
можно запланировать scan()
. Но есть проблема, некоторые задания выполняются дважды.
Я хочу убедиться, что в данный момент обрабатывается только одна работа. Как я могу этого достичь? Я полагаю, что это как-то связано done()
(это было в scan (), сейчас удалено), но я не смог найти решение.
Бык версия: 3.12.1
Важное позднее редактирование: scan()
вызывает другие функции, и они могут или не могут вызывать другие функции, но все они являются функциями синхронизации, поэтому они вызывают функцию только тогда, когда их собственные задания завершены, есть только один путь вперед. В конце «дерева», я его называю, последняя функция вызывает scheduleScan (), но не может быть запущено два одновременных задания. Между scan()
прочим, каждая работа начинается сscheduleScan(stock, period, milliseconds, 'called by file.js')
export function update(job) {
// does some calculations, then it may call scheduleScan() or
// it may call another function, and that could be the one calling
// scheduleScan() function.
// For instance, a function like finalize()
}
export function scan(job) {
update(job)
}
import moment from 'moment'
import stringHash from 'string-hash'
const opts = { redis: { port: 6379, host: '127.0.0.1', password: mypassword' } }
let queue = new Queue('scan', opts)
queue.process(1, (job) => {
job.progress(100).then(() => {
scan(job)
})
})
export function scheduleScan (stock, period, milliseconds, triggeredBy) {
let uniqueId = stringHash(stock + ':' + period)
queue.getJob(uniqueId).then(job => {
if (!job) {
if (milliseconds) {
queue.add({ stock, period, triggeredBy }, { delay: milliseconds, jobId: uniqueId }).then(() => {
// console.log('Added with ms: ' + stock + ' ' + period)
}).catch(err => {
if (err) {
console.log('Can not add because it exists ' + new Date())
}
})
} else {
queue.add({ stock, period, triggeredBy }, { jobId: uniqueId }).then(() => {
// console.log('Added without ms: ' + stock + ' ' + period)
}).catch(err => {
if (err) {
console.log('Can not add because it exists ' + new Date())
}
})
}
} else {
job.getState().then(state => {
if (state === 'completed') {
job.remove().then(() => {
if (milliseconds) {
queue.add({ stock, period, triggeredBy }, { delay: milliseconds, jobId: uniqueId }).then(() => {
// console.log('Added with ms: ' + stock + ' ' + period)
}).catch(err => {
if (err) {
console.log('Can not add because it exists ' + new Date())
}
})
} else {
queue.add({ stock, period, triggeredBy }, { jobId: uniqueId }).then(() => {
// console.log('Added without ms: ' + stock + ' ' + period)
}).catch(err => {
if (err) {
console.log('Can not add because it exists ' + new Date())
}
})
}
}).catch(err => {
if (err) {
// console.log(err)
}
})
}
}).catch(err => {
// console.log(err)
})
}
})
}
источник
scan
функцию, вы можете помочь?Ответы:
Проблема, я считаю, в том, что ваша
scan
функция асинхронна. Таким образом, вашаjob.progress
функция вызывает,scan
а затем немедленно вызывает,done
позволяя очереди обрабатывать другое задание.Решением может быть передача
done
обратного вызова в качестве параметра вашим функциямscan
иscheduleScan
функциям и вызов его после завершения работы (или по ошибке).Другим (лучшим) решением может быть обеспечение того, чтобы вы всегда возвращали
Promise
отscan
иscheduleScan
, а затем ожидали обещания решить и затем вызывалиdone
. Если вы делаете это, убедитесь, что вы включили все свои обещания в своюscheduleScan
функцию.источник
scheduledScan
что всегда вызывается после всех других функций синхронизации вscan
. Если это так, то да, мой ответ остается в силе. Просто всегда возвращает обещание , которое будет возвращено изscheduleScan
вscan
функцииupdate
звонкиscheduledScan
или любое количество функций между ними. Ключевым моментом является то, что вам нужно вернуть цепочку обещаний наscheduleScan
всем пути назад кscan
функции. Так что еслиscan
вызовы,update
вызывающиеfinalise
..... Какие вызовыscheduleScan
цепочки обещаний, должны быть возвращены через все вызовы функций, т.е. просто убедитесь, что вы возвращаете обещание от каждой из этих функций.Функция сканирования является асинхронной функцией. В вашей
queue.process()
функции вы должны дождаться функции сканирования и затем вызватьdone()
обратный вызов.Попробуй это! Я попытался немного изменить код, используя async-await.
источник