Cloud Pub/Sub で非同期 HTTP API 的なことをやってみる実験
非同期 HTTP API のようなことをやりたいのだけど、pubsub でどうにかできないかという実験。
どのようなことをやりたい?
以下のような、何かしら実行すると別のユーザー(handler)がスマートフォンやブラウザーで応答するまで待つという処理。発端としては MFA のようなフローをやりたかった。
こういうのは Durable Functiuons の出番のようだけど今回は pubsub でどうにかできないかと。
Pub/Sub をどう使う?
下記のようなフローを考えている。上記のリンクを見てると、もう一つ function
を作って user
側でポーリング(location で振る)するのがよいらしいが、簡素化のためにとりあえず下記の形で試す(user
側は単独の curl
などで簡単に処理したい)。
このフローの場合、function
が実行状態になっている時間が長くなる。pull の待ちは CPU をあまり消費しなさそうだが消費しまくるようなら別の方法を考える方向で。
試してみる
簡単なコードで試してみた。なお、ファンクション的なサービスは利用せずにローカルで動かしている(topic などは実際の project 上で作成している)。
概要。
- 受信側:
reqid
を引数としてあたえるとフィルター付きサブスクリプションを作成しサブスクライバーになる(pull して ackする) - 送信側:
reqid
とdata
を引数としてあたえるとreqid
をattributes
へセットしてdata
をパブリッシュする
とりあえずは想定していた通りに動きそう。
- 応答はフィルターで(ユーザーの要求別に)振り分けできる
- 複数同時に待ち受けもできる
- 実は、最初はサブスクリプションを 1 つだけで試してみたのだが、サブスクライバーを複数動かすと最後の 1 つしか反応しなかった
ちょっと、というかかなり気になるのは、サブスクリプション作成は(トピックではなく)プロジェクトに対してサブスクリプション作成の権限が必要なこと(どのようなサブスクリプションを作れるかは制限できないもよう?)。
また、サブスクリプション作成には意外と時間がかかるということ(数秒はかかっている)。気軽にほいほい作るものではない?とりあえず、今回の用途なら worker
側と並列するように動かせば気にならないか。
サブスクリプションとメッセージの保存期間を短くしておけば変に再送などで「やってしまった」なことにはならさそうかな(と思いたい)。
あとは、 worker
側は GAS で動かしたいのだけど GAS に pubsub 用のライブラリーがなかったのが悲しい。
試してみたら GAS からでもパブリッシュできた。
やったこと。
- SA 作っておいて下記のページを参考に Bearer にセットするトークンを取得
- POST 用の URL などは Method: projects.topics.publish の Try this method から切り貼り
このまま GAS からパブリッシュするかは少し悩み中。