আমি কীভাবে এটি নিশ্চিত করতে পারি যে বুলে দু'বার কোনও চাকরি চলে না?


11

আমার দুটি ফাংশন আছে, scheduleScan()এবং scan()

scan()কলগুলি scheduleScan() যখন নতুন স্ক্যানের সময় নির্ধারণ ব্যতীত আর কিছুই করার থাকে না , তাই scheduleScan()সময়সূচী করতে পারে scan()। তবে সমস্যা আছে, কিছু কাজ দু'বার চালায়।

আমি নিশ্চিত করতে চাই যে কোনও নির্দিষ্ট সময়ে যে কোনও সময়ে প্রক্রিয়াজাত হচ্ছে। আমি কীভাবে এটি অর্জন করতে পারি? আমি বিশ্বাস করি এর সাথে কিছু করার আছে done(), (এটি স্ক্যানে ছিল (), এখন সরানো হয়েছে) তবে আমি সমাধান দিয়ে আসতে পারিনি।

ষাঁড় সংস্করণ: 3.12.1

গুরুত্বপূর্ণ দেরী সম্পাদনা: scan() অন্য ফাংশনগুলিকে কল করে এবং তারা অন্য ফাংশনগুলিকে কল করতে বা নাও বলতে পারে, তবে তারা সমস্ত সিঙ্ক ফাংশন, তাই কেবলমাত্র তাদের নিজস্ব কাজ শেষ হলে একটি ফাংশন কল করে, কেবলমাত্র একটি পথ এগিয়ে যায়। "ট্রি" এর শেষে, আমি এটিকে বলি, শেষ ফাংশনটি শিডিউল স্ক্যানকে কল করে (), তবে দুটি যুগপত কাজ চলছে না। প্রতিটি একক কাজ শুরু 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ফাংশন সন্ধান করতে অক্ষম , আপনি সাহায্য করতে পারেন?
মুহাম্মদ জিশান

@ মুহাম্মাদজিশন আমি এটি যুক্ত করেছি, আমার ভুল।
বিক্রয়

উত্তর:


6

সমস্যা, আমি বিশ্বাস করি আপনার scanফাংশন অ্যাসিঙ্ক nc সুতরাং আপনার job.progressফাংশন কলscan এবং তারপরে তাত্ক্ষণিকভাবে কলের সাথে doneঅন্য কোনও কাজ প্রক্রিয়া করার অনুমতি দেয়।

doneআপনার পরামিতি হিসাবে কলব্যাকটি পাস করার একটি সমাধান হতে পারেscan এবং scheduleScanফাংশনগুলির , এবং আপনি একবার কাজ শেষ করার পরে (বা ত্রুটিযুক্ত) এটিকে প্রার্থনা করতে পারেন।

আরেকটি (ভাল) সমাধান তা নিশ্চিত করার জন্য আপনি সবসময় একটি ফিরতি হতে পারে Promiseথেকে scanএবং scheduleScanতারপর, সমাধান এবং তারপর কল প্রতিশ্রুতি অপেক্ষা done। এটি করা হলে, নিশ্চিত হয়ে নিন যে আপনি আপনার scheduleScanকার্যক্রমে আপনার সমস্ত প্রতিশ্রুতি ফেরতের শৃঙ্খলাবদ্ধ ।

queue.process(1, (job, done) => {
  job.progress(100).then(() => {
    scan(job)
        .then(done)
        .catch(done)
  })
})

export function scan() {
   // business logic
   return scheduleScan()
}

// Chain all of your promise returns. Otherwise
// the scan function will return sooner and allow done to be called
// prior to the scheduleScan function finishing it's execution
export function scheduleScan() {
    return queue.getJob(..).then(() => {
        ....
        return queue.add()...
        ....
        return queue.add(...)
            .catch(e => {
                 console.log(e);
                 // propogate errors!
                 throw e;
             })

}

আমি আমার প্রশ্নটি সম্পাদনা করেছি, আপনি কি এটি আবার পরীক্ষা করে দেখতে পারেন, বিশেষত "গুরুত্বপূর্ণ দেরী সম্পাদনা" অংশটি? আপনার উত্তর এখনও এই পরিস্থিতিতে প্রয়োগ হয়? ধন্যবাদ।
বিক্রয়

1
হ্যাঁ, এটি এখনও বৈধ। আপনার সম্পাদনা থেকে, আমি মনে করি আপনি যা বলছেন scheduledScanতা সবসময় অন্যান্য সিঙ্ক ফাংশনের পরে ডাকা হয় scan। যদি এটি হয় তবে হ্যাঁ, আমার উত্তরটি এখনও বৈধ। কেবল সর্বদা সেই প্রতিশ্রুতি ফিরিয়ে দিন scheduleScanযা scanফাংশন থেকে ফিরে আসবে
জিভস

আবার, আমার ভুল। প্রথম ফাংশন, আপডেট (), স্ক্যানে রয়েছে, তবে আপডেট () চূড়ান্তকরণ () এর মতো অন্য ফাংশনটিকে কল করতে পারে, এবং চূড়ান্তকরণ () শিডিউলস্ক্যানকে কল করতে পারে ()। দয়া করে মনে রাখবেন যে এটিগুলি একটি ক্রমে ঘটেছিল, তাই কোনও একাধিক কল নেই, আমি আমার অ্যাপ্লিকেশনটিকে মডিউল রাখার জন্য এটি করছি। - ধন্যবাদ
বিক্রয়

1
হ্যাঁ, একই উত্তর। যদি updateকল scheduledScanবা তাদের মধ্যে কোনও ক্রিয়াকলাপ মূল কথাটি হ'ল আপনাকে ফাংশনে scheduleScanফিরে সমস্ত দিক থেকে প্রতিশ্রুতি চেইনটি ফিরিয়ে দিতে scanহবে। সুতরাং যদি scanকলগুলি updateযা কল করে finalise..... যা scheduleScanপ্রতিশ্রুতি শৃঙ্খলা কল করে সমস্ত ফাংশন অনুরোধের মাধ্যমে ফেরত পাঠানো দরকার, অর্থাত্ নিশ্চিত করুন যে আপনি এই প্রতিটি কার্য থেকে প্রতিশ্রুতি ফিরিয়ে দিয়েছেন।
জিভস

সুতরাং শুধু আমার শেষ মন্তব্যটি স্পষ্ট করতে। উদাহরণস্বরূপ, স্ক্যানের ভিতরে থাকলে আপনি কল কল করুন আপডেট। আপনাকে স্ক্যান ফাংশন থেকে আপডেটের প্রতিশ্রুতি (প্রতিশ্রুতি) ফিরিয়ে দিতে হবে।
জিভস

4

স্ক্যান ফাংশন একটি অ্যাসিক্রোনাস ফাংশন। আপনার queue.process()ফাংশনে আপনাকে স্ক্যান ফাংশনটির জন্য অপেক্ষা করতে হবে এবং তারপরে done()কলব্যাকটি কল করতে হবে ।

export async function scan(job) {
  // it does some calculations, then it creates a new schedule.
  return scheduleScan(stock, period, milliseconds, "scan.js");
}

queue.process(1, (job, done) => {
  job.progress(100).then(async() => {
    await scan(job);
    done();
  });
});

export async function scheduleScan(stock, period, milliseconds, triggeredBy) {
    let uniqueId = stringHash(stock + ":" + period);
    try {
      const existingJob = await queue.getJob(uniqueId);
      if (!existingJob) {
        const job = await addJob({
          queue,
          stock,
          period,
          uniqueId,
          milliseconds,
          triggeredBy
        });
        return job;
      } else {
        const jobState = await existingJob.getState();
        if (jobState === "completed") {
          await existingJob.remove();
          const newJob = await addJob({
            queue,
            stock,
            period,
            uniqueId,
            milliseconds,
            triggeredBy
          });
          return newJob;
        }
      }
    } catch (err) {
      throw new Error(err);
    }
}

export function addJob({ queue, stock, period, milliseconds, triggeredBy }) {
  if (milliseconds) {
    return queue.add(
      { stock, period, triggeredBy },
      { delay: milliseconds, jobId: uniqueId }
    );
  } else {
    return queue.add({ stock, period, triggeredBy }, { jobId: uniqueId });
  }
}

এটা চেষ্টা কর! আমি অ্যাসিঙ্ক-ওয়েভেট ব্যবহার করে কোডটি কিছুটা রিফ্যাক্টর করার চেষ্টা করেছি।


আমি আমার প্রশ্নটি সম্পাদনা করেছি, আপনি কি এটি আবার পরীক্ষা করে দেখতে পারেন, বিশেষত "গুরুত্বপূর্ণ দেরী সম্পাদনা" অংশটি? আপনার উত্তর এখনও এই পরিস্থিতিতে প্রয়োগ হয়? ধন্যবাদ।
বিক্রয়
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.