728x90

- Task Scheduling 이란?

클라이언트에서 요청한 로직을 수행하는게 아닌, 서버에서 주기적으로 작업을 실행하는 것

  • 메일링 리스트에 추천 영화 리스트를 주기적으로 보내줄때.
  • 총 좋아요 갯수나 총 조회수처럼 특정 데이터를 주기적으로 업데이트할때.
  • 주기적으로 데이터나 파일을 정리할때.
  • 주기적으로 데이터 분석 리포트를 제작할때
  • 주기적으로 데이터베이스를 백업할때

- Cron 배우기(강의를 많이 캡처해서 비공개 처리함)

https://springdream0406.tistory.com/196


- NestJS Schedule 선언형

@Injectable()
export class TasksService {
    private readonly logger = new Logger(TasksService.name)

    @Cron('45 * * * * *')
    handleCron(){
        this.logger.debug('Called when the current second is')
    }
}

- NestJS Schedule 옵션

@Injectable()
export class NotificationService {
  @Cron('* * 0 * * *', {
    name: 'notifications',
    timeZone: 'Europe/Paris',
  })
  triggerNotifications() {}
}

- SchedulerRegistry 함수

addCronJob(name: string, seconds: string) {
    const job = new CronJob(`${seconds} * * * * *`, () => {
      this.logger.warn(`time (${seconds}) for job ${name} to run!`);
    });

    this.schedulerRegistry.addCronJob(name, job);
    job.start();

    this.logger.warn(
      `job ${name} added for each minute at ${seconds} seconds!`,
    );
  }
  • stop() : 예정된 작업을 중지한다.
  • start() : stop()이 실행된 작업을 재실행한다.
  • setTime(time: Crontime) : 작업을 중지하고 새로운 주기를 생성하고 시작한다.
  • lastDate() : 마지막으로 작업이 실행된 날짜를 반환한다.
  • nextDate() : 다음으로 작업이 실행될 날짜를 반환한다.
  • nextDates(count: number) : 다음으로 작업이 실행될 날짜들을 n개 반환한다.

여기까지 오면 너무 복잡해진다고 함. 보통 선언형에서 만족.


- 설치

yarn add @nestjs/schedule

 

- 잉여 파일(temp) 삭제 기능

// app.module.ts

imports: [
    ScheduleModule.forRoot(),
  ],
// tasks.service.ts

@Injectable()
export class TasksService {
  constructor() {}

  @Cron('* * * * * *')
  async eraseOrphanFiles() {
    const files = await readdir(join(process.cwd(), 'public', 'temp'));

    const deleteFilesTargets = files.filter((file) => {
      const filename = parse(file).name;

      const split = filename.split('_');

      if (split.length !== 2) return true; // 삭제에 포함

      try {
        const date = +new Date(parseInt(split[split.length - 1]));
        const aDayInMilSec = 24 * 60 * 60 * 1000;

        const now = +new Date();

        return now - date > aDayInMilSec;
      } catch (e) {
        return true;
      }
    });

    // 병렬 - 리소스 부담 커짐
    await Promise.all(
      deleteFilesTargets.map((x) =>
        unlink(join(process.cwd(), 'public', 'temp', x)),
      ),
    );

    // 직렬 - 시간 오래 걸림
    // for (let i = 0; i < deleteFilesTargets.length; i++) {
    //   const fileName = deleteFilesTargets[i];

    //   await unlink(join(process.cwd(), 'public', 'temp', fileName));
    // }
  }
}

unlink() : 삭제

// common.module.ts

providers: [
    TasksService,
  ],

 

- 좋아요, 싫어요 통계

유저들의 movie like/dislike를 movie에 바로바로 반영하지 않고, 1분에 한번씩 db 데이터 가져다가 update 시켜주는 방식

@Cron('0 * * * * *')
  async calculateMovieLikeCounts() {
    await this.movieRepository.query(
      `
UPDATE movie m
SET "likeCount" = (
  SELECT count(*) FROM movie_user_like mul
  WHERE m.id = mul."movieId" AND mul."isLike" = true
)`,
    );
    await this.movieRepository.query(
      `
UPDATE movie m
SET "dislikeCount" = (
  SELECT count(*) FROM movie_user_like mul
  WHERE m.id = mul."movieId" AND mul."isLike" = false
)`,
    );
  }

위 코드에서 Cron부분만 첨부함. (1분마다 실행)

update의 set에 서브쿼리를 넣어서 사용한게 신기함.

 

- SchedulerRegistry 함수 예시

constructor(
    private readonly schedulerRegistry: SchedulerRegistry,
  ) {}


@Cron('* * * * * *', {
    name: 'printer',
  })
  printer() {
    console.log('print every seconds');
  }

  @Cron('*/5 * * * * *')
  stopper() {
    console.log('---stopper run---');

    const job = this.schedulerRegistry.getCronJob('printer');

    console.log('# Last Date');
    console.log(job.lastDate());
    console.log('# Next Date');
    console.log(job.nextDate());
    console.log('# Next Dates');
    console.log(job.nextDates(5));

    if (job.running) {
      job.stop();
    } else {
      job.start();
    }
  }

위에서 언급했듯이. 웬만하면 쓰지 말아라. 쓰려면 모니터링 할 수 있는 거 마련해라.


https://fastcampus.co.kr/classroom/239666

 

커리어 성장을 위한 최고의 실무교육 아카데미 | 패스트캠퍼스

성인 교육 서비스 기업, 패스트캠퍼스는 개인과 조직의 실질적인 '업(業)'의 성장을 돕고자 모든 종류의 교육 콘텐츠 서비스를 제공하는 대한민국 No. 1 교육 서비스 회사입니다.

fastcampus.co.kr

 

 

728x90

'코딩 > Nest.js' 카테고리의 다른 글

Versioning  (0) 2024.10.27
Logging  (2) 2024.10.26
Caching  (2) 2024.10.25
Multer  (0) 2024.10.25
Custom Decorator  (1) 2024.10.24

+ Recent posts