###### tags: `Rust` `redis` `simple_redis` # Rust Simple_Redis Redisをより簡単に使うことのできるライブラリ いわゆる、redis-rsのラッパー ```toml= [dependencies] simple_redis = "*" ``` # 概要 - 本家redis-rsほど包括的、柔軟ではない - 一般的なユースケースをもっとシンプルなAPIで実装できる - redisクライアントだけでAPI全体にアクセス - pubsubインスタンスの管理が必要なく、クライアントだけですべて管理できる - 自動で復元力がある内部接続とサブスクリプション - ここは本家redis-rsより上 - 自動でつなぎ直すためのping操作コストが少し掛かる # 注意点 simple_redisのクライアントには、Syncトレイトが実装されていないので MutexやRwLock, Arcなどを使ってスレッドセーフなリソースにすることができない db.rs などでグローバルなクライアント変数にするのではなく、 使うたびに client を接続することになる。 マルチスレッドにすると、クライアントがスレッドごとに作られて 同時接続数がすごいことになるので注意 # 使い方 ## 接続 ```rust= extern crate simple_redis; let client match simple_redis::create("redis://127.0.0.1/") { Ok(mut client) => println!("Created Redis Client"); client, Err(error) => println!("Unable to create Redis client: {}", error) } ``` ## Clientを使ったredis操作 詳しくは simple_redis の Client構造体の API Reference https://docs.rs/simple_redis/0.3.44/simple_redis/client/struct.Client.html#method.get ## キーセット・取得 - 引数の型を自動変換 - 戻り値の型を明示的に指定 ```rust= match client.set("my_key", "my_value") { Err(error) => println!("Unable to set value in Redis: {}", error), _ => println!("Value set in Redis") }; match client.get_string("my_key") { Ok(value) => println!("Read value from Redis: {}", value), Err(error) => println!("Unable to get value from Redis: {}", error) }; // 数値型を扱う match client.set("my_numeric_key", 255.5) { Err(error) => println!("Unable to set value in Redis: {}", error), _ => println!("Value set in Redis") }; match client.get::<f32>("my_numeric_key") { Ok(value) => println!("Read value from Redis: {}", value), Err(error) => println!("Unable to get value from Redis: {}", error) }; ``` ポイント - .set() : 任意の型の引数に対応 - .get::\<T>() : 任意の型をGET、ジェネリックパラメータで型を指定 - .get_string(): 必ずstring型で取得 ## run_command() : 好きなコマンドを実行 ```rust= /// run some command that is not built in the library match client.run_command::<String>("ECHO", vec!["testing"]) { Ok(value) => assert_eq!(value, "testing"), _ => panic!("test error"), }; ``` ポイント - 戻り値の方を ::\<T> のジェネリックで指定 - 第一引数 = コマンド - 第二引数 = vec! 引数 ## pubsub ### publish ```rust= /// publish messages let mut result = client.publish("news_channel", "test message"); assert!(result.is_ok()); ``` ポイント - .publish() - 第一引数でチャンネル名 - 第二引数でメッセージ ### subsclibe まず、チャンネル名を指定してsubsclibeモードに ```rust= /// subscribe to channels result = client.subscribe("important_notifications"); assert!(result.is_ok()); // パターンマッチングでもsubscribeできる result = client.psubscribe("*_notifications"); assert!(result.is_ok()); ``` 次に、 client.get_message(timeout)で待ち受ける ```rust= loop { // fetch next message (wait up to 5 seconds, 0 for no timeout) match client.get_message(5000) { Ok(message) => { let payload: String = message.get_payload().unwrap(); assert_eq!(payload, "my important message") }, Err(error) => println!("Error while fetching message, should retry again, info: {}", error), } } ``` ポイント - timeoutには ミリ秒で待受時間を入れる - 0 だとタイムアウトなし(無限待ち) - タイムアウトするとErr() - 受信するとOk(message) - message - redis-rs の Msg構造体と同じもの - .get_payload() : 中身を取り出す(Result)