[WASM] Redis Trigger のアプリを試す [Spin]
Introduction
ここではHttpトリガーのプロジェクトを作成したので、
今回はRedisトリガーのプロジェクトを作成します。
Redisトリガーのプロジェクトでは、
任意のRedis Channelに対して、データがpublishされたタイミングで
Spinのコンポーネントを実行させることができます。
Env
- MacBook Pro (13-inch, M1, 2020)
- OS : MacOS 11.3.1
- rust : 1.61.0
- redis : 7.0.0
Setup
まずはRedisをインストールします。
Homebrewでインストール可能です。
% brew install redis
Redisを起動させておきます。
% redis-server or % brew services start redis
Try
Httpトリガーのプロジェクト(spin-http)と
Redisトリガーのプロジェクト(spin-redis)を作成します。
spin-httpdeではHTTPのクエリパラメータで指定した文字列を
ローカルのRedisへpublishします。
spin-redisではRedisにデータがpublishされたタイミングで
コンポーネントが起動し、そのデータをログに出力するようにします。
Create Redis Trigger Project
まずはRedisトリガーのプロジェクトを作成します。
spin newコマンドでredis-rustタイプのプロジェクトを作成します。
% spin new redis-rust ・・・
spin.tomlはデフォルトのままでOKです。
localhost:6379のRedis(channelはmessages)に対して
データがpublishされるとコンポーネントが起動します。
spin_version = "1" authors = ["someone"] description = "spin redis" name = "spin-redis" trigger = { type = "redis", address = "redis://localhost:6379" } version = "0.1.0" [[component]] id = "spin-redis" source = "target/wasm32-wasi/release/spin_redis.wasm" [component.trigger] channel = "messages" [component.build] command = "cargo build --target wasm32-wasi --release"
lib.rsではprintln!でうけとったデータを出力しています。
結果は~/.spin/<Project名>/logsのログファイルに出力されます。
use anyhow::Result; use bytes::Bytes; use spin_sdk::redis_component; use std::str::from_utf8; #[redis_component] fn on_message(message: Bytes) -> Result<()> { println!("{}", from_utf8(&message)?); Ok(()) }
spun upして動作確認してみます。
% cd path/your/spin-redis % spin build --up Executing the build command for component spin-redis: cargo build --target wasm32-wasi --release Finished release [optimized] target(s) in 0.82s Successfully ran the build command for the Spin components. 2022-06-03T08:27:29.305761Z TRACE build: spin_engine: Created module for component spin-redis from file 2022-06-03T08:27:29.305787Z TRACE build: spin_engine: Created pre-instance from module for component spin-redis. 2022-06-03T08:27:29.305790Z TRACE build: spin_engine: Execution context initialized. 2022-06-03T08:27:29.305880Z INFO spin_redis_engine: Connecting to Redis server at redis://localhost:6379 2022-06-03T08:27:29.307808Z INFO spin_redis_engine: Subscribed component #0 (spin-redis) to channel: messages
redis-cliでメッセージをpublishしてみます。
% redis-cli 127.0.0.1:6379> publish messages "hello from redis-cli" (integer) 1
spin-redisのログ(私の環境では~/.spin/spin-redis/logs/spin-redis_stdout.txt)
をみてみると、publishした文字列が記述されています。
Create Http Trigger Project
次にHttpトリガーのSpinアプリを作成し、/publishリクエスト時に
Redisへpublishするようにします。
Httpトリガーのプロジェクトを作成。
% spin new http-rust
spin.tomlは下記。
environmentを使うと、spin.tomlで定義した値を
コンポーネントで使えます。
spin_version = "1" authors = ["someone"] description = "spin http project" name = "spin-http" trigger = { type = "http", base = "/" } version = "0.1.0" [[component]] environment = { REDIS_ADDRESS = "redis://localhost:6379", REDIS_CHANNEL = "messages" } id = "spin-http" source = "target/wasm32-wasi/release/spin_http.wasm" [component.trigger] route = "/publish" [component.build] command = "cargo build --target wasm32-wasi --release"
コンポーネントではクエリ文字列を取得して
Redisにpublishしてます。
なお、constで定義している変数はspin.tomlで定義した値に置き換えられます。
use anyhow::{Result}; use spin_sdk::{ http::{internal_server_error, Request, Response}, http_component, redis, }; const REDIS_ADDRESS_ENV: &str = "REDIS_ADDRESS"; const REDIS_CHANNEL_ENV: &str = "REDIS_CHANNEL"; #[http_component] fn publish(req: Request) -> Result<Response> { let address = std::env::var(REDIS_ADDRESS_ENV)?; let channel = std::env::var(REDIS_CHANNEL_ENV)?; //get query string let param = match req.uri().query() { Some(p) if p.len() > 0 => p.as_bytes(), _ => "Foo".as_bytes(), }; println!("{:?}",param); // Publish to Redis match redis::publish(&address, &channel, ¶m) { Ok(()) => Ok(http::Response::builder().status(200).body(Some("OK".into()))?), Err(_e) => internal_server_error(), } }
spin upで起動します。
% cd path/your/spin-http % spin build --up Executing the build command for component spin-http: cargo build --target wasm32-wasi --release Compiling spin-http v0.1.0 Finished release [optimized] target(s) in 0.92s Successfully ran the build command for the Spin components. Serving HTTP on address http://127.0.0.1:3000 Available Routes: spin-http: http://127.0.0.1:3000/publish
クエリ文字列をつけて/publishにリクエストします。
% curl -i http://localhost:3000/publish?redis-trigger-from-http HTTP/1.1 200 OK content-length: 2 date: Fri, 03 Jun 2022 08:42:20 GMT OK
spin-redis_stdout.txtを見ると、
クエリ文字列が記録されているのがわかります。
Summary
というわけで、SpinのRedisトリガーを試してみました。
次はRedisをAmazon MemoryDB for Redis にしてみて動くか確認する(かもしれない)。