프로그래밍 언어/NODE JS

스케줄링 구현하기

· 코딩마이데이

경매가 생성되고 24시간이 지난 후에 낙찰자를 정하는 시스템을 구현해야 합니다. 이럴 때 node-shedule  모듈을 사용해야 합니다.

$ npm i node-schedule

 

routes/index.js

const express = require("express");
const multer = require("multer");
const path = require("path");
const fs = require("fs");
const schedule = require("node-schedule");

const { Good, Auction, User, sequelize } = require("../models");
const { isLoggedIn, isNotLoggedIn } = require("./middlewares");

const router = express.Router();

router.use((req, res, next) => {
  res.locals.user = req.user;
  next();
});

router.get("/", async (req, res, next) => {
  try {
    const goods = await Good.findAll({ where: { SoldId: null } });
    res.render("main", {
      title: "NodeAuction",
      goods,
    });
  } catch (error) {
    console.error(error);
    next(error);
  }
});

router.get("/join", isNotLoggedIn, (req, res) => {
  res.render("join", {
    title: "회원가입 - NodeAuction",
  });
});

router.get("/good", isLoggedIn, (req, res) => {
  res.render("good", { title: "상품 등록 - NodeAuction" });
});

try {
  fs.readdirSync("uploads");
} catch (error) {
  console.error("uploads 폴더가 없어 uploads 폴더를 생성합니다.");
  fs.mkdirSync("uploads");
}
const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, "uploads/");
    },
    filename(req, file, cb) {
      const ext = path.extname(file.originalname);
      cb(
        null,
        path.basename(file.originalname, ext) + new Date().valueOf() + ext,
      );
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 },
});
router.post(
  "/good",
  isLoggedIn,
  upload.single("img"),
  async (req, res, next) => {
    try {
      const { name, price } = req.body;
      const good = await Good.create({
        OwnerId: req.user.id,
        name,
        img: req.file.filename,
        price,
      });
      const end = new Date();
      end.setDate(end.getDate() + 1);
      schedule.scheduleJob(end, async () => {
        const success = await Auction.findOne({
          where: { GoodId: good.id },
          order: [["bid", "DESC"]],
        });
        await Good.update(
          { SoldId: success.userId },
          { where: { id: good.id } },
        );
        await User.update(
          {
            money: sequelize.literal(`money - ${success.bid}`),
          },
          {
            where: { id: success.userId },
          },
        );
      });
      res.redirect("/");
    } catch (error) {
      console.error(error);
      next(error);
    }
  },
);

module.exports = router;

 

schedule 객체의 scheduleJob 메서드로 일정을 예약할 수 있습니다. 첫 번째 인수로 실행될 시각을 넣고, 두 번째 인수로 해당 시각이 되었을 때 수행할 콜백 함수를 넣습니다. 경매 모델에서 가장 놓은 가격으로 입찰한 사람을 찾아 상품 모델의 낙찰자 아이디에 넣어주도록 정의했습니다. 또한, 낙찰자의 보유 자산을 낙찰 금액만큼 뺍니다. { 컬럼: sequelize.iternal(컬럼 - 숫자) } 가 시퀄라이즈에서 해당 컬럼의 숫자를 줄이는 방법입니다. 숫자를 늘리려면 - 대신 + 하면 됩니다.