💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۵ محسن محمدخانی
یک schedule سفارشی با nodeJS
کیوان علی محمدی حل شده توسط کیوان علی محمدی

سلام
فرض کنیم یک فرم داریم که داخلش کاربر یک زمان مشخصی وارد میکنه و کاریکه قرار انجام بشه

  <h1>enter your date and job</h1>
    <form>
      <input type="date" name="date-run-job"/>
      <select name="job">
          <option>Download file</option>
          <option>Get Date from Api</option>
          <option>Send Notification</option>
      </select>
      <button type="submit">send</button>
    </form>

با کد زیر , میشه این  پیاده سازی کرد

var CronJob = require("cron").CronJob;
const dateNow = new Date();
console.log(dateNow);
const specifyTime=dateNow.setSeconds(dateNow.getSeconds() + 3);
let newDate = new Date(specifyTime);
var job = new CronJob(
  newDate,
  function () {
    console.log("do job");
  },
  null,
  true  
);


اما اگر بخواهیم که اون کار غیرفعالش کنیم یا تاریخشو تغییر بدیم قاعدتا باید اونو داخل یک جایی ذخیره کنیم .اون جا میتونه یک جدول mySql یا داخل Mongodb یا هر جای دیگه ذخیره بشه
اگر فرض کنیم داخل یک جدول قراره ذخیره بشه ما جدولی داریم با ستون‌های زیر
id
title_job
execute_at
state
created_at
updated_at
تاریخ و ساعت اجرا کار در execute_at  ذخیره میشه و state هم فعال یا غیر فعال بودن یا اجراشدن و ... رو ذخیره میکنه
اما چطوری nodeJS متوجه بشه که وقت اجرا کدوم ردیف هستش؟
برای این میتونیم که setInterval به مدت یک ثانیه بذاریم که ردیف هایی که زمان فعلی با زمان execute_at برابر بود پیدا کنه و کارشو اجرا کنه که من فکر میکنم کار خوبی نیست
از طرفی اون کار که گفتیم منتظرش باش سر وقتش انجامش بدی و براش schedule  قرار دادیم اگر غیرفعالش کردیم چطوری به  nodeJS  بگیم که اجراش نکنه یا اگر تاریخش ویرایش شد چطوری متوجه این ویرایش تاریخ بشه
آیا برای چنین وضعیتی در نرم افراز , ابزارهای خاصی وجود داره؟

سلام. به نظرم بهترین روش اضافه کردن ستونی برای تنظیم تاریخ اجرای بعدی هستش مثلا یک ستون با نام 

next run date در نظر بگیرید و در زمان اجرای تسک تاریخ اجرای بعدی رو در این ستون به روز کنید و در نهایت بر اساس وضعیت هر تسک و تاریخ انجام اون می‌تونید این مساله رو حل کنید.

کیوان علی محمدی ۱۲ آذر ۱۳۹۹، ۰۸:۰۱

استاد مشکل اصلی اینه که NodeJs باید بصورت خودکار متوجه بشه که زمان جاری سرور برابر با زمان کدوم یک از  فیلد‌های execute_at هستش

بذارید بیشتر توضیح بدم
به جدول که آپلود شده توجه کنید. سه تا ستون داره یکی از آنها دارای تاریخ هستش 
سه تا ردیف هم داخل جدول هستش یکی برای امروز ساعت (۲۰۲۰-۱۲-۰۲ ۱۶:۲۴:۵۶) و یکی دیگه برای فردا ساعت (۲۰۲۰-۱۲-۰۳ ۱۷:۴۷:۲۱) و دیگری برای ۶ روز بعد ساعت  (۲۰۲۰-۱۲-۰۸ ۱۶:۲۶:۲۰)
من می‌خوام وقتیکه زمان جاری برابر با زمان هر کدوم از فیلد‌های مورد نظر برسه mySql یا NodeJS بصورت خودکار متوجه بشه و  به من این اطلاع بده که زمان الان برابر با زمان یکی از فیلدها رکورد جدول هستش. بدون اینکه من ازش بخوام بره داخل جدول بگرده 
من میتونم یک setInterval  به مدت یک ثانیه بذارم که جدول جستجو کنه و اگر زمان جاری با زمان هرکدوم از فیلدهای جدول شد به من اطلاع بده.اما این کار اصلا بهینه نیست
یه برنامه قرار ملاقات تصور کنید .شما یک ملاقات اضافه می‌کنید که داخلش شما یک تاریخ  ساعت و یک عنوان درج می‌کنید

برنامه باید ۱۰ دقیقه قبل به شما یک اطلاع رسانی بصورت sms یا  email یا هرچیزی بفرسته که شما ملاقات فراموش نکنید.

در اینجا اون کار باید بصورت خودکار و بدون عامل انسانی انجام بشه

این روشی که شما گفتید برای وقتیکه که من یک جدول فقط برای schedule‌های که درست میکنم بسازم

اما من می‌خوام بصورت خودکار همه چیز انجام بشه
 

محسن محمدخانی ۱۲ آذر ۱۳۹۹، ۰۸:۲۲

شما کافیه یک cron خارج از کد و توسط os تنظیم کنید که هر ثانیه اجرا بشه و توی اون ماژول که توسط cron اجرا میشه هر کاری می‌تونید انجام بدید. 

کیوان علی محمدی ۱۲ آذر ۱۳۹۹، ۰۸:۲۶

ممنون

چطوری میتونم اینکار انجام بدم؟امکانش هست یک منبع بفرستید

آیا این روش بهینه هست؟

شما خودتون تو این حالت از چه راه حلی استفاده میکنید؟

محسن محمدخانی ۱۲ آذر ۱۳۹۹، ۰۸:۳۲

قطعا این روش بهینه است چون زمان بندی توسط خود os انجام میشه و شما نباید نگران این باشید. فقط باید سعی کنید اون کدی که قرار در cron اجرا بشه رو کاملا بهینه بنویسید.

می تونید مثل زیر یک فایل bash درست کنید که بر اساس node آدرس فایل رو بهش بدید تا اجرا کنه. فقط حواستون باشه آدرس script باید کامل باشه و relative آدرس ندید.

 

#!/usr/bin/env sh  
node /home/user/project/script.js > /home/user/project/script-cron.log

بعدش در تنظیمات cron سرور یه دستوری رو مثل این تنظیم کنید. این دستور هر ثانیه اجرا میشه.

* * * * * /path_to_bash_file/bash.sh
بهترین پاسخ
کیوان علی محمدی ۱۲ آذر ۱۳۹۹، ۰۸:۴۱