ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • node-schedule, node-cron 이용하기
    Project 2021. 5. 19. 11:01

    myoku.co.kr

    오쿠는 경매사이트다.

    마감시간 이후 낙찰자를 지정해줘야하는데, 이 때 node-schedule 모듈을 이용했다.

    Note that Node Schedule is designed for in-process scheduling, i.e. scheduled jobs will only fire as long as your script is running, and the schedule will disappear when execution completes. If you need to schedule jobs that will persist even when your script isn't running, consider using actual cron.

    공식문서에서도 볼 수 있듯이, node-schedule은 스크립트가 실행될 때에만 작동을 하고, 만약 실행되지않는다면 예약되어있던 스케쥴이 모두 사라진다.

     

    그래서 두가지 방법을 생각해봤는데 

    1. AWS lambda를 이용해서 특정 시간마다 함수를 호출하기
    2. 공식문서에서 추천한대로 cron을 이용해서 특정시간마다 함수를 호출하기

    우선 첫번째 방법으로 시도해보려고했지만, lambda에서 내가 사용한 함수를 호출하는것이 어려울것이라고 판단했다.

    그리고 굳이 이것까지 써야하나? 싶어서 2번으로 결정.

     

    처음 접하는것이라서 어려울 줄 알았는데, node-cron모듈을 사용하니 생각보다 쉽게 사용할 수 있었다.

     

    우선 낙찰자를 정해주는 코드는 아래와 같다.

    checkAuction.js

    const Product = require("../schema/product");
    const PriceHistory = require("../schema/pricehistory");
    
    module.exports = async () => {
    	console.log("checkAuction");
    	try {
    		const today = new Date();
    		today.setDate(today.getDate());
    
    		//낙찰자가 정해지지않은 제품들, 마감기한이 지난 제품
    		const targets = await Product.find({
    			soldBy: null,
    			deadLine: { $lte: today },
    		});
    		// console.log(
    		// 	"====서버가 꺼지면서 낙찰자가 안정해진 것들====",
    		// 	targets.length
    		// );
    
    		targets.forEach(async (target) => {
    			const success = await PriceHistory.find({
    				productId: target._id,
    			});
    			console.log("==success==", success);
    			// 입찰자가 1명 이상인 경우
    			if (success.length !== 0) {
    				await target.updateOne({
    					$set: {
    						onSale: false,
    						soldBy: success[0].nickName,
    						sodById: success[0].userId,
    					},
    				});
    				//console.log("====서버가 켜지면서 낙찰자가 지정됨===", success.length);
    			} else {
    				// 입찰자가 없을 경우
    				await target.updateOne({
    					$set: {
    						onSale: false,
    						soldBy: "-",
    						soldById: "-",
    					},
    				});
    			}
    		});
    		//console.log("====서버가 켜질 때 낙찰자 없음===", targets.length);
    	} catch (error) {
    		console.error(error);
    	}
    };
    

    그리고 위 코드를 app.js가 실행된 후 1분마다 한번씩(..) 실행시킨다.

    처음엔 아 이거 너무 서버에 부하가 되는행동 아닐까..? 하는 고민을 했는데

    아직까지 ec2프리티어에서 과금도 안되고있고...해서 과금이 되면 그 때 고민해볼까 한다..

    노드가 가볍기도해서ㅎㅎ..

     

    app.js

    // main 연결페이지
    const express = require("express");
    const app = express();
    require("dotenv").config();
    const cron = require("node-cron");
    const helmet = require("helmet");
    const path = require("path");
    
    app.use(cors());
    
    //많은것을 생략..
    
    // second minute hour day-of-month month day-of-week
    cron.schedule("1* * * * *", function () {
    	checkAuction();
    });
    
    
    const server = app.listen(port, () => {
    	console.log(`Server start at http://localhost:${port}`);
    });
    
    webSocket(server, app);
    

     

    그런데 다 짜고나서 생각해보니까.

    1분마다 checkAuction을 하면 굳이 node-schedule을 쓸 필욘 없지 않나?

    하는 생각이 들었다.. 하핫..

Designed by Tistory.