Saya memiliki dua fungsi, scheduleScan()
dan scan()
.
scan()
panggilan scheduleScan()
saat tidak ada lagi yang harus dilakukan selain menjadwalkan pemindaian baru , jadi scheduleScan()
dapat menjadwalkan a scan()
. Tapi ada masalah, beberapa pekerjaan berjalan dua kali.
Saya ingin memastikan bahwa hanya satu pekerjaan yang sedang diproses pada waktu tertentu. Bagaimana saya bisa mencapainya? Saya percaya ini ada hubungannya done()
, (sudah dalam pemindaian (), dihapus sekarang) tapi saya tidak bisa menemukan solusi.
Versi banteng: 3.12.1
Edit terlambat yang penting: scan()
memanggil fungsi lain dan mereka mungkin atau mungkin tidak memanggil fungsi lain, tetapi mereka semua fungsi sinkronisasi, jadi mereka hanya memanggil fungsi ketika pekerjaan mereka sendiri selesai, hanya ada satu jalan ke depan. Pada akhir "tree", saya menyebutnya, fungsi terakhir memanggil scheduleScan (), tetapi tidak mungkin ada dua pekerjaan simultan yang berjalan. Setiap pekerjaan dimulai scan()
, dengan cara, dan mereka berakhir denganscheduleScan(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)
})
}
})
}
sumber
scan
fungsi, dapatkah Anda membantu?Jawaban:
Masalahnya, saya percaya
scan
fungsi Anda async. Jadijob.progress
fungsi Anda memanggilscan
dan kemudian segera memanggildone
memungkinkan antrian untuk memproses pekerjaan lain.Sebuah solusi bisa dengan meneruskan
done
panggilan balik sebagai parameter untuk Andascan
danscheduleScan
fungsinya, dan memohonnya, setelah Anda menyelesaikan pekerjaan Anda (atau karena kesalahan).Solusi (yang lebih baik) lainnya adalah memastikan bahwa Anda selalu mengembalikan a
Promise
dariscan
danscheduleScan
, kemudian menunggu janji untuk menyelesaikan dan kemudian menelepondone
. Jika melakukan ini, pastikan Anda mengaitkan semua janji Anda kembali dalamscheduleScan
fungsi Anda .sumber
scheduledScan
selalu dipanggil setelah semua fungsi sinkronisasi lainnya masukscan
. Jika ini masalahnya, maka ya, jawaban saya masih valid. Hanya selalu kembali janji yang akan kembali darischeduleScan
dalamscan
fungsiupdate
panggilanscheduledScan
atau sejumlah fungsi di antara mereka. Poin kuncinya adalah Anda harus mengembalikan rantai janji darischeduleScan
semua jalan kembali kescan
fungsi. Jadi, jikascan
panggilanupdate
yang memanggilfinalise
..... Yang memanggilscheduleScan
rantai janji harus dikembalikan melalui semua pemanggilan fungsi, yaitu Pastikan Anda mengembalikan janji dari masing-masing fungsi ini.Fungsi pemindaian adalah fungsi asinkron. Dalam
queue.process()
fungsi Anda, Anda harus menunggu fungsi pemindaian dan kemudian memanggil panggilandone()
balik.Coba ini! Saya sudah mencoba untuk sedikit memperbaiki kode dengan menggunakan async-wait.
sumber