Agenda

특정 시간 혹은 주기로 어떤 작업을 처리해야 할때 리눅스의 크론(Cron)을 사용한다. 노드에서는 cron-node 모듈을 이용해 프로그래밍 단에서 크론잡을 관리할 수 있다. 단일 잡일 경우 간단히 구현할 수 있지만 처리해야할 잡의 종류가 많아지면 그만큼 관리하기 복잡하고 힘들어질 수 있다. Agenda는 여러개의 크론 잡을 관리하기 위한 노드 모듈이다.

설치

$ npm install agenda

모듈 로딩

// index.js
var Agenda = require("agenda")

디비 연결

var agenda = new Agenda({ db: { address: "localhost:27017/agenda-sample" } })

agenda 라이브러리는 잡을 등록하고 잡에 대한 정보를 유지할 목적으로 몽고디비를 사용한다. 데이터베이스 주소만 파라매터로 넘기면 모듈 내부에서는 agendaJobs 컬렉션을 사용한다.

태스크 정의

agenda.define("tick", function (job, done) {
  console.log("agenda sample " + job.attrs.data.by)
  done()
})

agenda.define() 함수로 태스크를 생성할 수 있다. 첫번째 파라매터에 태스크 이름 'tick'을 넘겨주고 두번째 콜백함수를 태스트로 설정하였다.

콜백함수의 첫번째 job 파라매터는 나중에 정의한 태스크를 구동할 때 넘겨주는 객체 정보를 포함하고 있다. 태스크가 완료되면 두번째 파라매터인 done 콜백 함수를 실행한다.

예약

agenda.every("3 seconds", "tick", { by: "chris" })

agenda.every() 함수로 위에서 정의한 'tick' 태스크를 예약한다. 매 3초마다 'tick' 태스크를 수행하도록 한다. 세번째 파라매터에 객체를 넘겨주는데, 이 객체는 태스크크가 수행될 때 job.attrs.data 에 할당되어 들어간다. 그래서 boj.attrs.data.by로 접근하면 설정한 문자열인 'chris' 값을 얻을 수 있는 것이다.

실행

agenda.start()

마지막으로 agenda.start() 함수로 실행한다. 등록한 태스크를 실행하는 것이 아니라 태스크의 예약을 실행한다고 봐야한다. 실제 동작은 3초 후에 일어난다. 첫번째 파라매터는 크론타임을 입력하는데 '3 seconds' 문자열을 입력할 수도 있다. 원래는 * * * * * 형식으로 입력해야하는데 모듈 내부에서 human-interval 모듈을 사용하기 때문에 'seconds, 'minutes', 'hours'등 문자열로 입력할 수 있다.

결과

실행하면

node index.js

아래 결과를 확인할 수 있다.

agenda sample chris
agenda sample chris
agenda sample chris
...

몽고 디비를 살펴보면 등록한 'tick' 태스크를 확인할 수 있다.

{
  "_id" : ObjectId("55f182936af636482289a854"),
  "name" : "tick",
  "type" : "single",
  "data" : {
    "by" : "chris"
  },
  "priority" : 0,
  "repeatInterval" : "3 seconds",
  "lastModifiedBy" : null,
  "nextRunAt" : ISODate("2015-09-10T13:16:15.915Z"),
  "lockedAt" : ISODate("2015-09-10T13:16:13.871Z"),
  "lastRunAt" : ISODate("2015-09-10T13:16:12.915Z"),
  "lastFinishedAt" : ISODate("2015-09-10T13:16:12.917Z")
}

태스크 이름(name), 사용자 데이터(data), 스케쥴링 정보(repeatInterval), 다음 실행시간(nextRunAt) 등을 확인할 수 있다.

참고

전체코드: https://github.com/jeonghwan-kim/agenda-sample