Ich habe zwei Funktionen scheduleScan()
und scan()
.
scan()
Anrufe , scheduleScan()
wenn es nichts anderes außer der Planung eines neuen Scan zu tun , so scheduleScan()
kann ein Zeitplan scan()
. Es gibt jedoch ein Problem: Einige Jobs werden zweimal ausgeführt.
Ich möchte sicherstellen, dass jeweils nur ein Auftrag bearbeitet wird. Wie kann ich das erreichen? Ich glaube, es hat etwas damit zu tun done()
(es wurde in scan () entfernt), aber ich konnte keine Lösung finden.
Bull Version: 3.12.1
Wichtige späte Bearbeitung: scan()
Ruft andere Funktionen auf und sie können andere Funktionen aufrufen oder nicht, aber sie sind alle Synchronisierungsfunktionen. Daher rufen sie eine Funktion nur auf, wenn ihre eigenen Jobs abgeschlossen sind. Es gibt nur einen Weg vorwärts. Am Ende des "Baums" nenne ich es, die letzte Funktion ruft ScheduleScan () auf, aber es können nicht zwei Jobs gleichzeitig ausgeführt werden. Jeder einzelne Job beginnt scan()
übrigens bei und endet mitscheduleScan(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)
})
}
})
}
quelle
scan
Funktion finden. Können Sie mir helfen?Antworten:
Ich glaube, das Problem ist, dass Ihre
scan
Funktion asynchron ist. Ihrejob.progress
Funktion ruft also aufscan
und ruft dann sofort auf,done
sodass die Warteschlange einen anderen Job verarbeiten kann.Eine Lösung könnte darin bestehen, den
done
Rückruf als Parameter an Ihrescan
undscheduleScan
Funktionen zu übergeben und ihn aufzurufen, sobald Sie Ihren Job abgeschlossen haben (oder wenn ein Fehler aufgetreten ist).Eine andere (bessere) Lösung könnte darin bestehen, sicherzustellen, dass Sie immer ein
Promise
von zurückgebenscan
undscheduleScan
dann auf das Versprechen warten, es zu lösen, und dann anrufendone
. Stellen Sie in diesem Fall sicher, dass Sie alle Ihre Versprechen in IhrerscheduleScan
Funktion verketten .quelle
scheduledScan
wird immer nach allen anderen Synchronisierungsfunktionen in aufgerufenscan
. Wenn dies der Fall ist, ist meine Antwort immer noch gültig.scheduleScan
scan
update
AnrufescheduledScan
oder eine beliebige Anzahl von Funktionen zwischen ihnen. Der entscheidende Punkt ist, dass Sie die Versprechen-Kette vomscheduleScan
gesamten Weg zurück zurscan
Funktion zurückgeben müssen. Wenn alsoscan
Aufrufeupdate
welche Aufrufefinalise
..... welche AufrufescheduleScan
die Versprechenskette aufrufen, müssen alle Funktionsaufrufe zurückgegeben werden, dh stellen Sie einfach sicher, dass Sie das Versprechen von jeder dieser Funktionen zurückgeben.Die Scanfunktion ist eine asynchrone Funktion. In Ihrer
queue.process()
Funktion müssen Sie auf die Scanfunktion warten und dann dendone()
Rückruf aufrufen .Versuche dies! Ich habe versucht, den Code mit async-await ein wenig umzugestalten.
quelle