この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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 にしてみて動くか確認する(かもしれない)。