mcpField
S
swift-valkey

swift-valkey

github.com/wendylabsinc開発6267 回インストール5 週間前に更新
リポジトリ

swift-valkey について

swift-valkeyは、Swift開発者向けのValkey/Redisクライアントライブラリです。async/awaitに対応し、単一サーバーやクラスターへの接続に加え、データ構造操作、Pub/Sub、トランザクション、パイプライン、クラスター内ルーティングを提供します。

主な機能

  1. 01Swiftのasync/awaitクライアント
  2. 02単一サーバーまたはクラスターへの接続
  3. 03文字列、ハッシュ、リスト、セットに対応
  4. 04Pub/Subメッセージング
  5. 05トランザクションとパイプライン実行
  6. 06キーのハッシュスロットによるコマンド振り分け

活用シーン

  1. 01SwiftアプリでValkeyまたはRedisのデータを読み書き
  2. 02クラスター構成でシャーディングされたデータにアクセス
  3. 03Pub/Subによる通知の送信
  4. 04コマンドの一括実行やトランザクション処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wendylabsinc/claude-skills --skill swift-valkey

インストール後、Claude Code で/swift-valkeyを入力して読み込まれたか確認します。

同梱ファイルreferences/valkey-patterns.md

詳細

Valkey / Redis

Valkey は、オープンソースの高性能なキー・バリューストア(Redis のフォーク)です。valkey-swift ライブラリは、完全な async/await サポート、クラスターのルーティング、Pub/Sub を備えた Swift クライアントを提供します。

クイックスタート

インストール

Package.swift に追加します:

dependencies: [
    .package(url: "https://github.com/valkey-io/valkey-swift.git", from: "1.0.0")
]
基本的な使い方
import Valkey

// Connect to single server
let client = try await ValkeyClient.connect(to: .init(host: "localhost", port: 6379))

// Basic operations
try await client.set("key", "value")
let value = try await client.get("key") // Optional<String>

// With expiration
try await client.set("session", sessionData, expiration: .seconds(3600))

// Delete
try await client.del("key")
クラスターモード
// Connect to cluster
let client = try await ValkeyClient.connect(
    to: .cluster([
        .init(host: "node1.redis.local", port: 6379),
        .init(host: "node2.redis.local", port: 6379),
        .init(host: "node3.redis.local", port: 6379)
    ])
)

// Commands automatically route to correct shard
try await client.set("user:123", userData)

コマンド

文字列
// SET with options
try await client.set("key", "value", condition: .nx)  // Only if not exists
try await client.set("key", "value", condition: .xx)  // Only if exists
try await client.set("key", "value", expiration: .milliseconds(5000))

// GET
let value = try await client.get("key")

// INCR/DECR
let newValue = try await client.incr("counter")
let decreased = try await client.decr("counter")
try await client.incrBy("counter", 10)
ハッシュ
try await client.hset("user:123", field: "name", value: "Alice")
try await client.hset("user:123", fields: ["name": "Alice", "email": "[email protected]"])

let name = try await client.hget("user:123", field: "name")
let user = try await client.hgetall("user:123") // [String: String]
リスト
try await client.lpush("queue", "item1", "item2")
try await client.rpush("queue", "item3")

let item = try await client.lpop("queue")
let items = try await client.lrange("queue", start: 0, stop: -1)
セット
try await client.sadd("tags", "swift", "redis", "backend")
let isMember = try await client.sismember("tags", "swift")
let members = try await client.smembers("tags")
ソート済みセット
try await client.zadd("leaderboard", score: 100, member: "player1")
try await client.zadd("leaderboard", members: [("player2", 200), ("player3", 150)])

let top10 = try await client.zrange("leaderboard", start: 0, stop: 9, withScores: true)
let rank = try await client.zrank("leaderboard", member: "player1")

Pub/Sub

// Subscribe to channels
let subscription = try await client.subscribe(to: ["notifications", "updates"])

// Process messages
for try await message in subscription {
    switch message {
    case .message(let channel, let payload):
        print("Received on \(channel): \(payload)")
    case .subscribe(let channel, let count):
        print("Subscribed to \(channel)")
    }
}

// Publish
try await client.publish("notifications", message: "Hello subscribers!")

// Pattern subscribe
let patternSub = try await client.psubscribe(to: ["user:*", "event:*"])

トランザクション

// MULTI/EXEC transaction
let results = try await client.transaction(
    SET("key1", "value1"),
    SET("key2", "value2"),
    GET("key1")
)
// Results is tuple: (Result<String?, Error>, Result<String?, Error>, Result<String?, Error>)

パイプライン処理

// Execute multiple commands in single round-trip
let (setResult, getResult, incrResult) = try await client.execute(
    SET("key", "value"),
    GET("key"),
    INCR("counter")
)

クラスタールーティング

キーのハッシュスロットに基づいて、コマンドは適切なシャードに自動的にルーティングされます:

// Keys with same hash tag go to same shard
try await client.set("{user:123}:profile", profileData)
try await client.set("{user:123}:settings", settingsData)
// Both keys route to same shard due to {user:123} hash tag

接続設定

let config = ValkeyClient.Configuration(
    endpoints: .single(.init(host: "localhost", port: 6379)),
    password: "secret",
    database: 0,
    connectionTimeout: .seconds(5),
    commandTimeout: .seconds(30),
    tls: .require(.makeClientConfiguration())
)

let client = try await ValkeyClient.connect(configuration: config)

エラー処理

do {
    let value = try await client.get("key")
} catch let error as ValkeyClientError {
    switch error {
    case .connectionClosed:
        // Reconnect logic
    case .timeout:
        // Retry logic
    case .serverError(let message):
        print("Server error: \(message)")
    }
}

リファレンスファイル

特定のトピックに応じて、以下のファイルを読み込んでください:

  • references/valkey-patterns.md - コマンドプロトコルのパターン、RESP のエンコード/デコード、ハッシュスロットを使用したクラスターのルーティング、サブスクリプション管理、トランザクションのパターン、コネクションプールの統合、モジュール拡張

コメント