Google Cloud Tasks API에서 30일 이상 작업을 예약하는 방법은 무엇인가요?

Mailmeteor에서는 Google Cloud Tasks에 크게 의존하여 이메일을 보냅니다. 실제로 이메일을 보낼 때마다 이메일과 연결된 하나 이상의 Cloud Tasks가 있습니다. 그것은 결국 많은 작업입니다.

Google의 제품은 정말 강력하지만 항상 까다로웠던 한 가지는 30일 이상 실행될 작업을 예약할 수 없다는 것입니다.


자원

설명


작업의 최대 일정 시간
현재 날짜 및 시간으로부터 30일
앞으로 작업을 예약할 수 있는 최대 시간입니다.


Google Cloud Tasks documentation on quotas & limits에서 추출

여전히 AWS가 제안하는 것보다 훨씬 더 많습니다(AWS SQS - Simple Queue Service - 최대 15분 동안 메시지를 대기열에 추가할 수 있음). 그럼에도 불구하고 매우 긴 작업 스케줄러가 필요한 사용 사례가 너무 많습니다.

Google이 실행 지연을 한 달로 제한한 이유를 잘 모르겠지만 직원 중 한 명이 StackOverflow에서 이러한 제한은 "설계 결정입니다. Google은 작업 저장 공간에 대한 비용을 청구하지 않으므로 확장하면 해로울 것입니다. 우리 비용으로."( source ).

하지만 Google Cloud Tasks는 이미 유료 제품입니다. 따라서 비용을 지불해야 하는지 여부에 관계없이 날짜를 연장하는 것은 그들에게 그다지 문제가 되지 않을 것입니다. 실제로 this StackOverflow thread 에 따르면 1,000 명 이상이 작업 지연 연장에 관심을 보였습니다. 그리고 2020년부터 이미 feature request이 있습니다. Google에서 우선 순위를 지정할 수 있도록 별표를 표시해 주시기 바랍니다.

말이 너무 많아. Google Cloud Tasks를 계속 사용하고 실행 지연을 "무한 이상으로"확장하는 방법을 살펴보겠습니다.

해결책



요령은 작업에 ETA 헤더를 추가하는 것입니다. 이렇게 하면 작업을 실행하기 전에 ETA가 현재인지(따라서 작업을 실행하는지) 또는 미래에 있는지(따라서 작업을 다시 예약할 수 있는지) 확인할 수 있습니다. 이렇게 하면 반복적으로 작업을 계속 생성하고 원하는 시간에 작업을 실행할 수 있습니다.

예를 들어 보겠습니다.
  • 45일 후에 실행할 작업이 있습니다
  • .
  • 최대 실행 시간(30일)으로 새 작업을 생성합니다
  • 다음:
  • 30일 후 작업이 실행되지만 너무 이르므로 45-30 = 14일로 다시 예약합니다
  • 14일 후(총 45일) 작업이 정상적으로 실행됩니다.


  • 실제로 그렇게 하면 지금부터 1년(또는 그 이상) 후에 작업을 생성하게 됩니다.

    구현(JS)



    Express.js에서 필요한 것은 실행 시간이 미래인지 확인하고 그렇다면 작업 일정을 재조정하는 미들웨어뿐입니다.

    // Middleware to reschedule Google Cloud Tasks
    export const googleTasksScheduleMiddleware = async (req, res, next) => {
      const taskETAHeader = req.headers['google-cloud-tasks-eta'];
    
      // If no header, skip middleware
      if(taskETAHeader == null || taskETAHeader == ""){
        next()
        return
      }
    
      const now = Date.now();
      const intHeader = parseInt(taskETAHeader);
    
      // Time has passed, let's process the task now
      if(intHeader < now) {
        next()
        return
      }
    
      // It's too early! Reschedule the task
      else {
        // Construct the task.
        createTask(req.method, req.url, req.headers, req.body)
    
        res.send('Re-scheduled')    
        return
      }
    }
    


    그런 다음 애플리케이션의 첫 번째 경로 앞에 중간을 추가합니다.

    app.use(googleTasksScheduleMiddleware)
    


    결론



    보시다시피 구현하기가 매우 쉽고 애플리케이션을 리팩토링할 필요가 없습니다. Mailmeteor의 더 많은 엔지니어링 기사에 관심이 있으시면 .

    좋은 웹페이지 즐겨찾기