どのようにGoogleのクラウドタスクAPIで30日以上のタスクをスケジュールするには?


MailMeteorでは、我々は電子メールを送信するためにGoogle Cloud Tasksに大きく頼ります.実際には、メールを送信するたびに、1つまたは複数のクラウドタスクが関連付けられています.それは最後にたくさんの仕事です.
Googleの製品は本当に堅牢ですが、常にトリッキーである1つのことは、30日以上で実行されるタスクをスケジュールすることはできませんです.
リソース

説明
タスクの最大スケジュール時間
現在の日時から30日
タスクがスケジュールできる将来の最大量.
Google Cloud Tasks documentation on quotas & limitsからの抽出物
AWSの提案(AWS SQS -シンプルなキューサービス-最大15分までのメッセージをキューにすることができます)よりもまだ方法です.それにもかかわらず、非常に長いタスクスケジューラを必要とする場合、非常に多くのユースケースがあります.
Googleがなぜ実行遅延を1ヵ月に制限したかについて、私が確信しなかった間、彼らの従業員のうちの1人はStackoverflowに関して説明しました、そのような限界は「デザイン決定です.(source)
Googleクラウドのタスクはすでに有料の製品です.それで、あなたがそれのために支払う必要があるかどうかに関係なく、日付を広げることは、彼らのためにそれの多くの問題でありません.実際には、this StackOverflow threadによると、1000人以上の人々は、タスクの遅延の拡大に興味を持っている.そしてすでに2020年からfeature requestがあります.そして、私はGoogleがこれを優先することを確認するためにあなたに星を要求します.
あまりにも多くの話.どのようにGoogleクラウドのタスクを使用し続けることができますし、実行遅延を“無限に超えて”をご覧ください.

解決策


トリックは、タスクにETAヘッダーを追加することです.このように、タスクを実行する前に、ETAが現在(そして、したがって、タスクを実行する)か、将来(そして、したがって、再スケジュールされたタスク)をチェックすることができます.あなたが再帰的にタスクを作成し、最終的にご希望の時間にタスクを実行し続けることができますこの方法.
例を挙げましょう.
  • 私は45日242479182で実行するタスクを持っている
  • 私はマックス実行時間(30日)
  • で新しいタスクを作成します
    その後、

  • 30日後、
  • は実行されます、しかし、それはあまりに早いです、それで、私は45 - 30 = 14日
  • でそれを再スケジュールします
    14日後の
  • (合計45日)、タスクは正常に実行されます.
  • 実際には、そうすることから1年(またはそれ以上)でタスクを作成しましょう.

    実装(JS)


    急行.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からより多くのエンジニアリング記事に興味があるならば、確認してください.