最近、Elixirを触ってみてるのですが、Cloud PubSubにElixirを使ってぶん投げるというコードを書いてみたのでメモ。
なお、ElixirはもちろんPubSubも今回初めて触ったので変なところあったら指摘が欲しいです。
PubSub準備
まずはトピックの作成
gcloud pubsub topics create first-topic
続いて、サブスクリプションの作成。これでpull型のサブスクリプションができる
gcloud pubsub subscriptions create first-topic-subscription --topic first-topic
動作確認をしてみます。
gcloud pubsub topics publish first-topic --message "hello pubsub"
PubSubにメッセージを送信できました。結果はGCPのコンソールとかから確認可能です。
Elixir
続いてElixir側のコードになります。
config
mix.exsにgothとgoogle_api_pub_subを足します。gothはGoogle OAuth
の略みたいです。
def application do
[
extra_applications: [:logger, :goth],
applications: applications(Mix.env)
]
end
defp deps do
[
{:google_api_pub_sub, "~> 0.16.0"},
{:goth, "~> 1.1.0"}
]
Authentication
ローカルで動かす場合はGOOGLE_APPLICATION_CREDENTIALS
の設定が必要です。サービスアカウントに適切な権限を設定してダウンロードして環境変数の設定をします。
Pub/Sub パブリッシャー
の権限が必要なのでこちらを対象のアカウントに紐づけておきます。
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service_account.json
サンプルの実行
対話シェルを使って動作確認をします。
iex -S mix
エラー処理はちゃんと書いてませんが、だいたい以下のコードで動きます。
project_id="${PROJCT ID}"
topic_name="first-topic"
m = Jason.encode!(message)
{:ok, token} = Goth.Token.for_scope("https://www.googleapis.com/auth/cloud-platform")
conn = GoogleApi.PubSub.V1.Connection.new(token.token)
# Build the PublishRequest struct
request = %GoogleApi.PubSub.V1.Model.PublishRequest{
messages: [
%GoogleApi.PubSub.V1.Model.PubsubMessage{
data: Base.encode64(m)
}
]
}
r = GoogleApi.PubSub.V1.Api.Projects.pubsub_projects_topics_publish(
conn,
project_id,
topic_name,
[body: request]
)
r = case r do
{:ok, response} -> response #IO.puts "published message #{response.messageIds}"
{:error, msg} -> IO.puts "published message #{msg}"
end
読めばそのままですが、まずGoogle OAuth
でアカウントを取得しています。
そして、メッセージ情報を作成しPublishしています。
メッセージ情報はディクショナリ型をJSON文字列に変換して渡しています。これで任意のデータ構造をCloud PubSubに送信することができます。
まとめ
基本的にはGitHub上のREADMEとHEXのドキュメントを参照してやった感じです。
Elixirマイナーだからライブラリあるかな? と失礼ながら心配だったけど特に問題なく利用できてよかったです。
GCPはゲームとかと親和性高いのでサーバを1からかけるExlixirも人気高いのかもしれないですね。
それではHappy Hacking!