Open5

Cloud Pub/Sub で非同期 HTTP API 的なことをやってみる実験

hankei6kmhankei6km

どのようなことをやりたい?

以下のような、何かしら実行すると別のユーザー(handler)がスマートフォンやブラウザーで応答するまで待つという処理。発端としては MFA のようなフローをやりたかった。

こういうのは Durable Functiuons の出番のようだけど今回は pubsub でどうにかできないかと。

https://learn.microsoft.com/ja-jp/azure/azure-functions/durable/durable-functions-overview?tabs=csharp#async-http

hankei6kmhankei6km

Pub/Sub をどう使う?

下記のようなフローを考えている。上記のリンクを見てると、もう一つ function を作って user 側でポーリング(location で振る)するのがよいらしいが、簡素化のためにとりあえず下記の形で試す(user 側は単独の curl などで簡単に処理したい)。

このフローの場合、function が実行状態になっている時間が長くなる。pull の待ちは CPU をあまり消費しなさそうだが消費しまくるようなら別の方法を考える方向で。

hankei6kmhankei6km

試してみる

簡単なコードで試してみた。なお、ファンクション的なサービスは利用せずにローカルで動かしている(topic などは実際の project 上で作成している)。

https://github.com/hankei6km/test-pubsub-pull

概要。

  1. 受信側: reqid を引数としてあたえるとフィルター付きサブスクリプションを作成しサブスクライバーになる(pull して ackする)
  2. 送信側: reqiddata を引数としてあたえると reqidattributes へセットして data をパブリッシュする

上記のテストコードを動かしている動画。ターミナルを3分割し2つのサブスクライバーがパブリッシュされたメッセージを個別に受け取っている様子が再生されている

とりあえずは想定していた通りに動きそう。

  • 応答はフィルターで(ユーザーの要求別に)振り分けできる
  • 複数同時に待ち受けもできる
    • 実は、最初はサブスクリプションを 1 つだけで試してみたのだが、サブスクライバーを複数動かすと最後の 1 つしか反応しなかった

ちょっと、というかかなり気になるのは、サブスクリプション作成は(トピックではなく)プロジェクトに対してサブスクリプション作成の権限が必要なこと(どのようなサブスクリプションを作れるかは制限できないもよう?)。

また、サブスクリプション作成には意外と時間がかかるということ(数秒はかかっている)。気軽にほいほい作るものではない?とりあえず、今回の用途なら worker 側と並列するように動かせば気にならないか。

サブスクリプションとメッセージの保存期間を短くしておけば変に再送などで「やってしまった」なことにはならさそうかな(と思いたい)。

あとは、 worker 側は GAS で動かしたいのだけど GAS に pubsub 用のライブラリーがなかったのが悲しい。

hankei6kmhankei6km

試してみたら GAS からでもパブリッシュできた。

やったこと。

  • SA 作っておいて下記のページを参考に Bearer にセットするトークンを取得
  • POST 用の URL などは Method: projects.topics.publish の Try this method から切り貼り

https://medium.com/@gw_cule/gasを使った認可パターン-67f195d7a425
https://github.com/googleworkspace/apps-script-oauth2

このまま GAS からパブリッシュするかは少し悩み中。