Open3

realtime database/firestoreで安めのタスクキューシステムが作れるんじゃないかという話

tkowtkow

MBaaSとしてFirebaseを使っている場合、非同期処理をredisやapp engineのタスクキューを使うとややネットワークの構成をいじる必要がある。また、event triggerやscheduler、pubsub単体では、event triggerを主体とするとコールドスタート時に実行速度が3secくらいのスピンアップがかかることがあるので、即応性が求められるタスクには向かない。また、タスクの失敗時の補償がしにくいため、ジョブをrealtime databaseもしくはfirestoreに投入して、cloud runまたは、minInstances: 1 && maxInstances: 1を設定して常駐させることでお安く使える可能性を模索するスレッド。

https://firebase.google.com/docs/functions/manage-functions?hl=ja

ちなみに最小構成タスクであれば月額6$+(realtimedatabase or firestore)の従量課金程度で運用可能である。普通にinstance常駐させたりmanagedなキューシステム使うよりはまぁ安くなる気がする。

ちなみにまだ検証はしていない。安定性に関しては確証がないので、本番で使う場合は自己責任で。また、event triggerを主体とするとコールドスタート時に実行速度が3secくらいのスピンアップがかかることがあるので、即応性が求められるタスクには向かないかもしれない。

Cloud Runを用いる場合

  1. job投入用のコレクションをrealtime databaseで作成
async_tasks: {
   [jobname: string]: {
       [job_id: string]: {
          params: any
          retry: 0
       }
   } 
}
  1. 常駐functionで監視したいjob_nameを指定し、collectionをsubscrbeする。

(擬似コード)

collection('job_name').querySnapshot((doc) => {
         task.run('job_name', doc.data())
})
  1. 実行が完了したらjobIdのドキュメントを消す。エラー吐いたらretryをincrementして、retryの閾値でエラーログを出力する

firebase functionsを使う場合

firebase functionsは実行時間に制限があるので常駐させることはできない。なので大人しく、realtime database/firestoreのwrite triggerあるいはpubsubを利用する。スピンアップ時間が気になる場合はminInstances:1を設定すれば常駐するようになる。retryの設定で気をつけないといけないのはcloud runでやったようなretry countを増やす方法でトリガーを再発火させる方法は意図せず無限発火するリスクがあるので避けた方が良いだろう。使う場合はテストを念入りにした方が良い。
エラーレポートを通知して再度pubsubにsendTopicするなどの運用方法で手動でエラー時にやり直せば十分なタスクであればpubsubを利用するのが良さそうだ。

(擬似コード)

onWrite((before, after) => {
      task.run('job_name',after.data())
})
// or
onTopic((topicData) => {
      task.run('job_name',topicData.json())
})

networkの構成なんて管理したくないからfirebaseしか使いたくないんだって人にはユースケースがありそうである。
自分で紹介しといてなんだが、僕自身はおそらくしばらくタスクキューを使うと思う。

tkowtkow

Gen2なら...!Gen2ならきっとなんとかしてくれる!
https://qiita.com/gzock/items/4ae721fad4ed09b3ba86
なんとcloud taskの実行がサポートされている。これによって、app engineを経由する事なくfirebase fucntions側だけの実装でcloud taskを完結できるようになったぽい。これは激アツ
https://firebase.google.com/docs/functions/beta/task-functions
endpointを自分で取得しなきゃいけないのが難点だがGoogle様ならそのうちAPIをにょきにょきはやしてくれるはず。
https://github.com/firebase/functions-samples/blob/3515b7f38a3c598cdb20152a263372e81719ecda/2nd-gen/taskqueues-backup-images/functions/index.js
GAに期待