### Install Hamster Library using go get Source: https://github.com/justinwongcn/hamster/blob/main/EXAMPLES.md This snippet demonstrates how to install the Hamster library using the `go get` command, which fetches the package and its dependencies into your Go workspace. ```bash go get github.com/justinwongcn/hamster ``` -------------------------------- ### Install Hamster Go Library Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This snippet shows how to install the Hamster Go library using the `go get` command, making it available for your Go projects. ```bash go get github.com/justinwongcn/hamster ``` -------------------------------- ### Initialize Hamster Services (Cache, Hash, Lock) Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This Go example demonstrates the basic initialization of Hamster's core services: Cache, Consistent Hash, and Distributed Lock. It also shows how to retrieve the Hamster library version, providing a quick start for integrating these functionalities. ```go package main import ( "context" "fmt" "time" "github.com/justinwongcn/hamster" "github.com/justinwongcn/hamster/cache" "github.com/justinwongcn/hamster/hash" "github.com/justinwongcn/hamster/lock" ) func main() { fmt.Printf("Hamster 版本: %s\n", hamster.GetVersion()) // 使用缓存 cacheService, _ := hamster.NewCache() cacheService.Set(context.Background(), "key", "value", time.Hour) // 使用一致性哈希 hashService, _ := hamster.NewConsistentHash() // 使用分布式锁 lockService, _ := hamster.NewDistributedLock() } ``` -------------------------------- ### Install Hamster Go Module Source: https://github.com/justinwongcn/hamster/blob/main/docs/USER_GUIDE.md This snippet demonstrates how to initialize a new Go module and install the Hamster library using `go mod init` and `go get` commands. This is the first step to integrate Hamster into your Go project. ```bash go mod init your-project go get github.com/justinwongcn/hamster ``` -------------------------------- ### Hamster Basic Cache Usage Example in Go Source: https://github.com/justinwongcn/hamster/blob/main/EXAMPLES.md This example demonstrates the fundamental steps to initialize Hamster's cache service, set a key-value pair with an expiration, and retrieve the value. It also shows how to get the Hamster library version, providing a quick start to its caching capabilities. ```go package main import ( "context" "fmt" "time" "github.com/justinwongcn/hamster" ) func main() { // 获取版本信息 fmt.Printf("Hamster 版本: %s\n", hamster.GetVersion()) // 创建缓存服务 cacheService, err := hamster.NewCache() if err != nil { panic(err) } ctx := context.Background() // 使用缓存 err = cacheService.Set(ctx, "key", "value", time.Hour) if err != nil { panic(err) } value, err := cacheService.Get(ctx, "key") if err != nil { panic(err) } fmt.Printf("缓存值: %v\n", value) } ``` -------------------------------- ### Go: Consistent Hashing Basic Node Management Source: https://github.com/justinwongcn/hamster/blob/main/EXAMPLES.md This example demonstrates the fundamental setup of a consistent hashing service in Go, including the configuration of virtual nodes and the optional singleflight mode for request deduplication. It shows how to add multiple server nodes with varying weights and then verifies the distribution of keys across these nodes to ensure balanced load. ```Go func consistentHashExample() { // 创建一致性哈希服务 hashService, err := hamster.NewConsistentHash( hash.WithReplicas(150), // 每个节点150个虚拟节点 hash.WithSingleflight(true), // 启用单飞模式 ) if err != nil { log.Fatalf("创建一致性哈希服务失败: %v", err) } ctx := context.Background() // 添加服务器节点 servers := []hash.Peer{ {ID: "server1", Address: "192.168.1.1:8080", Weight: 100}, {ID: "server2", Address: "192.168.1.2:8080", Weight: 100}, {ID: "server3", Address: "192.168.1.3:8080", Weight: 150}, // 更高权重 {ID: "server4", Address: "192.168.1.4:8080", Weight: 100}, } err = hashService.AddPeers(ctx, servers) if err != nil { log.Printf("添加节点失败: %v", err) return } fmt.Printf("✓ 成功添加 %d 个服务器节点\n", len(servers)) // 测试键分布 keys := []string{ "user:123", "user:456", "user:789", "session:abc", "session:def", "session:ghi", "cache:data1", "cache:data2", "cache:data3", } distribution := make(map[string]int) for _, key := range keys { peer, err := hashService.SelectPeer(ctx, key) if err != nil { log.Printf("选择节点失败: %v", err) continue } distribution[peer.ID]++ fmt.Printf("键 %-12s -> 节点 %s (%s)\n", key, peer.ID, peer.Address) } // 显示分布统计 fmt.Println("\n节点分布统计:") for serverID, count := range distribution { fmt.Printf("节点 %s: %d 个键\n", serverID, count) } } ``` -------------------------------- ### Example Usage of Consistent Hash Application Service in Go Source: https://github.com/justinwongcn/hamster/blob/main/internal/application/README.md Provides an example of how to initialize the Consistent Hash Application Service, add peers to the hash ring, and select a peer based on a given key. It demonstrates the basic workflow for distributed peer selection. ```go // Create application service hashMap := consistent_hash.NewConsistentHashMap(150, nil) picker := consistent_hash.NewSingleflightPeerPicker(hashMap) appService := NewConsistentHashApplicationService(picker) // Add nodes addCmd := AddPeersCommand{ Peers: []PeerRequest{ {ID: "server1", Address: "192.168.1.1:8080", Weight: 100}, {ID: "server2", Address: "192.168.1.2:8080", Weight: 100}, }, } err := appService.AddPeers(ctx, addCmd) if err != nil { log.Printf("Failed to add nodes: %v", err) return } // Select node selectCmd := PeerSelectionCommand{Key: "user:123"} result, err := appService.SelectPeer(ctx, selectCmd) if err != nil { log.Printf("Failed to select node: %v", err) return } fmt.Printf("User assigned to server: %s\n", result.Peer.ID) ``` -------------------------------- ### Create Hamster Consistent Hash Service with Default and Custom Configurations Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This Go example demonstrates how to initialize a Hamster consistent hash service, using either default settings or custom configurations such as the number of replicas (virtual nodes) and enabling single-flight optimization for improved performance. ```go // 使用默认配置 hashService, err := hamster.NewConsistentHash() // 使用自定义配置 hashService, err := hamster.NewConsistentHash( hash.WithReplicas(150), hash.WithSingleflight(true), ) ``` -------------------------------- ### Example Usage of ReadThroughCache Get Method Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/read_through_cache.md Demonstrates how to initialize and use the `ReadThroughCache`. It shows setting up the cache with a custom `LoadFunc` (simulating database access), configuring a log function, and retrieving data, handling potential errors. ```Go // 创建读透缓存 cache := &ReadThroughCache{ Repository: memoryCache, LoadFunc: func(ctx context.Context, key string) (any, error) { // 从数据库加载数据 return database.GetUser(key) }, Expiration: time.Hour, } // 设置日志函数 cache.SetLogFunc(log.Printf) // 获取数据 user, err := cache.Get(ctx, "user:123") if err != nil { log.Printf("获取用户失败: %v", err) return } fmt.Printf("用户信息: %v\n", user) ``` -------------------------------- ### Go Example: Implementing a New Data Structure (Stack) Source: https://github.com/justinwongcn/hamster/blob/main/internal/domain/tools/README.md Provides a conceptual example of how to extend the `tools` package by implementing a new generic data structure, specifically a Stack. It demonstrates defining an interface and a concrete array-based implementation with `Push` and `Pop` methods, showcasing the use of Go generics. ```go // 1. 定义接口 type Stack[T any] interface { Push(item T) Pop() (T, error) Peek() (T, error) IsEmpty() bool Size() int } // 2. 实现结构体 type ArrayStack[T any] struct { items []T } // 3. 实现方法 func (s *ArrayStack[T]) Push(item T) { s.items = append(s.items, item) } func (s *ArrayStack[T]) Pop() (T, error) { if len(s.items) == 0 { var zero T return zero, errors.New("栈为空") } item := s.items[len(s.items)-1] s.items = s.items[:len(s.items)-1] return item, nil } ``` -------------------------------- ### Go: Selecting Cache Patterns (Read-Through, Write-Back, Write-Through) Source: https://github.com/justinwongcn/hamster/blob/main/docs/PERFORMANCE.md Provides examples of instantiating different cache patterns—Read-Through, Write-Back, and Write-Through—based on specific use cases like read-heavy, write-heavy, or strong consistency requirements. Each pattern addresses distinct data access and consistency needs. ```Go readThroughCache := NewReadThroughCache(baseCache) // 写多读少的场景:使用写回缓存 writeBackCache := NewWriteBackCache(baseCache, time.Minute, // 刷新间隔 1000, // 批量大小 ) // 强一致性要求:使用写透缓存 writeThroughCache := NewWriteThroughCache(baseCache) ``` -------------------------------- ### RateLimitReadThroughCache Get Method and Usage Example Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/read_through_cache.md Presents the `Get` method for `RateLimitReadThroughCache`, which includes a check for rate-limiting via context. The example illustrates both normal data retrieval and how to simulate a rate-limited scenario where the `LoadFunc` is bypassed. ```Go func (r *RateLimitReadThroughCache) Get(ctx context.Context, key string) (any, error) ``` ```Go // 创建限流读透缓存 rateLimitCache := &RateLimitReadThroughCache{ Repository: memoryCache, LoadFunc: func(ctx context.Context, key string) (any, error) { return database.GetUser(key) }, Expiration: time.Hour, } // 正常访问 user, err := rateLimitCache.Get(ctx, "user:123") // 限流访问 limitedCtx := context.WithValue(ctx, "limited", true) user, err = rateLimitCache.Get(limitedCtx, "user:123") // 不会触发LoadFunc ``` -------------------------------- ### Go Consistent Hashing Service Example Source: https://github.com/justinwongcn/hamster/blob/main/docs/USER_GUIDE.md This Go example illustrates how to use Hamster's consistent hashing service. It shows how to create a `ConsistentHashPeerPicker`, add multiple peer nodes with weights, and then select a peer based on a given key for distributed node selection and load balancing. ```go package main import ( "fmt" "log" "github.com/justinwongcn/hamster/internal/application/consistent_hash" "github.com/justinwongcn/hamster/internal/infrastructure/consistent_hash" ) func main() { // 创建一致性哈希服务 peerPicker := consistent_hash.NewConsistentHashPeerPicker(150) // 150个虚拟节点 service := consistent_hash.NewConsistentHashApplicationService(peerPicker) // 添加节点 cmd := consistent_hash.AddPeersCommand{ Peers: []consistent_hash.PeerRequest{ {ID: "node1", Address: "192.168.1.1:8080", Weight: 100}, {ID: "node2", Address: "192.168.1.2:8080", Weight: 100}, {ID: "node3", Address: "192.168.1.3:8080", Weight: 100}, }, } if err := service.AddPeers(ctx, cmd); err != nil { log.Fatal(err) } // 选择节点 result, err := service.SelectPeer(ctx, consistent_hash.PeerSelectionCommand{ Key: "user:12345", }) if err != nil { log.Fatal(err) } fmt.Printf("Key %s 映射到节点: %s\n", result.Key, result.Peer.ID) } ``` -------------------------------- ### Go Example: Comprehensive LRUPolicy Usage Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/lru_policy.md Provides a series of Go code examples demonstrating the practical application of the `LRUPolicy`. This includes basic key access and size checks, manual eviction, retrieving keys in their access order, and observing automatic capacity management and eviction behavior. ```Go ``` -------------------------------- ### Go Basic Cache Repository Usage Example Source: https://github.com/justinwongcn/hamster/blob/main/internal/domain/cache/repository.md Demonstrates how to use the fundamental `Repository` interface for setting and retrieving cache values. This example illustrates basic cache operations and includes error handling for cache interactions. ```Go func ExampleBasicRepository(repo Repository) { ctx := context.Background() // Set cache err := repo.Set(ctx, "user:123", "John Doe", time.Hour) if err != nil { log.Printf("设置缓存失败: %v", err) return } // Get cache value, err := repo.Get(ctx, "user:123") if err != nil { log.Printf("获取缓存失败: %v", err) return } fmt.Printf("用户信息: %v\n", value) } ``` -------------------------------- ### Go Cache System Service Example Source: https://github.com/justinwongcn/hamster/blob/main/docs/USER_GUIDE.md This Go example demonstrates Hamster's caching system. It shows how to configure a cache policy with size limits, memory limits, default TTL, and eviction strategy (e.g., LRU), then set and retrieve data from the cache. This helps optimize performance by storing frequently accessed data. ```go package main import ( "context" "fmt" "log" "time" "github.com/justinwongcn/hamster/internal/application/cache" "github.com/justinwongcn/hamster/internal/infrastructure/cache" "github.com/justinwongcn/hamster/internal/domain/cache" ) func main() { // 创建缓存服务 policy := cache.NewCachePolicy(). WithMaxSize(1000). WithMaxMemory(100 * 1024 * 1024). // 100MB WithDefaultTTL(time.Hour). WithEvictionStrategy(cache.NewLRUEvictionStrategy()) repository := cache.NewInMemoryCacheRepository(policy) cacheService := cache.NewCacheService(cache.NewLRUEvictionStrategy()) appService := cache.NewApplicationService(repository, cacheService, nil) ctx := context.Background() // 设置缓存 setCmd := cache.CacheItemCommand{ Key: "user:12345", Value: map[string]interface{}{"name": "张三", "age": 30}, Expiration: time.Hour, } if err := appService.Set(ctx, setCmd); err != nil { log.Fatal(err) } // 获取缓存 getQuery := cache.CacheItemQuery{Key: "user:12345"} result, err := appService.Get(ctx, getQuery) if err != nil { log.Fatal(err) } fmt.Printf("缓存值: %+v\n", result.Value) } ``` -------------------------------- ### Hamster Consistent Hashing Go Examples Source: https://github.com/justinwongcn/hamster/blob/main/README.md Shows how to configure and interact with Hamster's consistent hashing service. Examples include adding peers with specified IDs, addresses, and weights, and selecting single or multiple peers based on a given key for load balancing or data distribution. ```go hashService, err := hamster.NewConsistentHash( hash.WithReplicas(150), hash.WithSingleflight(true), ) // 添加节点 peers := []hash.Peer{ {ID: "server1", Address: "192.168.1.1:8080", Weight: 100}, {ID: "server2", Address: "192.168.1.2:8080", Weight: 150}, } err = hashService.AddPeers(ctx, peers) // 选择节点 peer, err := hashService.SelectPeer(ctx, "user:123") // 选择多个节点(副本) peers, err := hashService.SelectPeers(ctx, "data:important", 3) ``` -------------------------------- ### Basic Write-Back Cache Usage in Go Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/write_back_cache.md This Go example demonstrates the fundamental setup and manual operation of a write-back cache. It initializes a cache with a memory-based backend and a custom storer function that simulates database writes. Data is added to the cache, and then a manual flush operation is triggered to persist the dirty data. ```Go package main import ( "context" "fmt" "log" "time" "github.com/justinwongcn/hamster/internal/infrastructure/cache" ) func main() { // 创建底层缓存 memoryCache := cache.NewMaxMemoryCache(1024 * 1024) // 1MB // 创建写回缓存 writeBackCache := cache.NewWriteBackCache( memoryCache, 30*time.Second, // 30秒刷新间隔 10, // 10个脏数据触发刷新 ) // 定义存储函数 storer := func(ctx context.Context, key string, val any) error { fmt.Printf("写入数据库: %s = %v\n", key, val) time.Sleep(10 * time.Millisecond) // 模拟数据库延迟 return nil } ctx := context.Background() // 写入数据(只更新缓存) for i := 1; i <= 5; i++ { user := map[string]interface{}{ "id": fmt.Sprintf("%d", i), "name": fmt.Sprintf("User%d", i), } err := writeBackCache.Set(ctx, fmt.Sprintf("user:%d", i), user, time.Hour) if err != nil { log.Printf("写入失败: %v", err) continue } fmt.Printf("写入用户%d到缓存\n", i) } fmt.Printf("脏数据数量: %d\n", writeBackCache.GetDirtyCount()) // 手动刷新 fmt.Println("手动刷新脏数据...") err := writeBackCache.Flush(ctx, storer) if err != nil { log.Printf("刷新失败: %v", err) } fmt.Printf("刷新后脏数据数量: %d\n", writeBackCache.GetDirtyCount()) } ``` -------------------------------- ### Example Usage of Standard Go Write-Through Cache Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/write_through_cache.md This comprehensive Go example demonstrates how to set up and use the `WriteThroughCache`. It initializes an in-memory cache and a mock database storer, then performs a write operation, showing how data is consistently updated in both the cache and the simulated persistent storage. ```Go package main import ( "context" "fmt" "log" "time" "github.com/justinwongcn/hamster/internal/infrastructure/cache" ) func main() { // 创建底层缓存 memoryCache := cache.NewMaxMemoryCache(1024 * 1024) // 1MB // 创建写透缓存 writeThroughCache := &cache.WriteThroughCache{ Repository: memoryCache, StoreFunc: createDatabaseStorer(), } ctx := context.Background() // 写入数据 user := map[string]interface{}{ "id": "123", "name": "John Doe", "age": 30, } fmt.Println("写入用户数据...") err := writeThroughCache.Set(ctx, "user:123", user, time.Hour) if err != nil { log.Printf("写入失败: %v", err) return } fmt.Println("写入成功,数据已同步到缓存和数据库") // 验证数据 cachedUser, err := writeThroughCache.Get(ctx, "user:123") if err != nil { log.Printf("获取缓存数据失败: %v", err) return } fmt.Printf("缓存中的用户数据: %v\n", cachedUser) } func createDatabaseStorer() func(context.Context, string, any) error { return func(ctx context.Context, key string, val any) error { fmt.Printf("写入数据库: %s = %v\n", key, val) // 模拟数据库写入延迟 time.Sleep(50 * time.Millisecond) // 模拟偶发的数据库错误 if key == "error:key" { return errors.New("数据库写入失败") } return nil } } ``` -------------------------------- ### Go Example: Read-Through Cache with Custom Loader Source: https://github.com/justinwongcn/hamster/blob/main/internal/application/cache/service.md Demonstrates the `GetWithLoader` method in action, showing how to implement a `loader` function that simulates fetching data from a database. This example highlights how the read-through pattern simplifies data retrieval by ensuring data is always available, either from cache or source. ```Go readThroughService := NewReadThroughApplicationService(repository, cacheService, readThroughRepo) loader := func(ctx context.Context, key string) (any, error) { return database.GetUser(key) } result, err := readThroughService.GetWithLoader(ctx, query, loader, time.Hour) if err != nil { log.Printf("读透获取失败: %v", err) return } fmt.Printf("获取到数据: %v\n", result.Value) ``` -------------------------------- ### Go Example: Write-Through Cache with Custom Storer Source: https://github.com/justinwongcn/hamster/blob/main/internal/application/cache/service.md Presents an example of using the `SetWithStore` method. It shows how to define a `storer` function that simulates saving a `User` object to a database, ensuring data consistency across cache and persistent storage in a single operation. ```Go writeThroughService := NewWriteThroughApplicationService(repository, cacheService, writeThroughRepo) storer := func(ctx context.Context, key string, val any) error { return database.SaveUser(key, val) } cmd := CacheItemCommand{ Key: "user:456", Value: User{ID: "456", Name: "Jane"}, Expiration: time.Hour, } err := writeThroughService.SetWithStore(ctx, cmd, storer) if err != nil { log.Printf("写透设置失败: %v", err) } ``` -------------------------------- ### Go Basic Cache Service Usage Example Source: https://github.com/justinwongcn/hamster/blob/main/internal/application/cache/service.md Demonstrates how to initialize and use the basic caching service in Hamster. This example covers setting cache items, retrieving them, and fetching cache statistics, illustrating fundamental cache operations and error handling. ```go package main import ( "context" "fmt" "log" "time" "github.com/justinwongcn/hamster/internal/application/cache" "github.com/justinwongcn/hamster/internal/domain/cache" infraCache "github.com/justinwongcn/hamster/internal/infrastructure/cache" ) func main() { // 创建基础设施 repository := infraCache.NewMaxMemoryCache(1024 * 1024) // 1MB cacheService := domainCache.NewCacheService(domainCache.NewLRUEvictionStrategy()) // 创建应用服务 appService := cache.NewApplicationService(repository, cacheService, nil) ctx := context.Background() // 设置缓存项 cmd := cache.CacheItemCommand{ Key: "user:123", Value: map[string]string{"name": "John", "email": "john@example.com"}, Expiration: time.Hour, } err := appService.SetCacheItem(ctx, cmd) if err != nil { log.Printf("设置缓存失败: %v", err) return } fmt.Println("缓存设置成功") // 获取缓存项 query := cache.CacheItemQuery{Key: "user:123"} result, err := appService.GetCacheItem(ctx, query) if err != nil { log.Printf("获取缓存失败: %v", err) return } if result.Found { fmt.Printf("找到缓存: %v\n", result.Value) } else { fmt.Println("缓存未命中") } // 获取统计信息 stats, err := appService.GetCacheStats(ctx) if err != nil { log.Printf("获取统计失败: %v", err) return } fmt.Printf("缓存统计: 命中=%d, 未命中=%d, 命中率=%.2f%%\n", stats.Hits, stats.Misses, stats.HitRate*100) } ``` -------------------------------- ### Install Hamster Go Library Source: https://github.com/justinwongcn/hamster/blob/main/docs/README.md This command installs the Hamster Go library into your Go module path, making it available for import in your Go projects. Ensure Go is properly configured on your system before running this command. ```bash go get github.com/justinwongcn/hamster ``` -------------------------------- ### Hamster Cache System Go Examples Source: https://github.com/justinwongcn/hamster/blob/main/README.md Illustrates how to initialize and use Hamster's cache services, including basic in-memory caching with eviction policies and read-through caching with a custom data loader function. These examples demonstrate setting maximum memory, eviction strategies, and integrating with external data sources. ```go // 基础缓存 cacheService, err := hamster.NewCache( cache.WithMaxMemory(1024*1024), cache.WithEvictionPolicy("lru"), cache.WithDefaultExpiration(time.Hour), ) // 读透缓存 readThroughCache, err := hamster.NewReadThroughCache( cache.WithMaxMemory(512*1024), ) loader := func(ctx context.Context, key string) (any, error) { return loadFromDatabase(key), nil } value, err := readThroughCache.GetWithLoader(ctx, "user:123", loader, time.Hour) ``` -------------------------------- ### Go RandomPolicy Basic Usage Example with Capacity Limit Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/random_policy.md Illustrates the fundamental usage of the `RandomPolicy` with a defined capacity. This example demonstrates how to create a policy, record key accesses, and observe how the policy automatically evicts keys when the capacity limit is reached, maintaining the specified size. ```go package main import ( "context" "fmt" "log" "github.com/justinwongcn/hamster/internal/infrastructure/cache" ) func main() { // 创建随机策略 policy := cache.NewRandomPolicy(3) // 容量限制为3 ctx := context.Background() // 记录访问 keys := []string{"key1", "key2", "key3", "key4"} for _, key := range keys { err := policy.KeyAccessed(ctx, key) if err != nil { log.Printf("记录访问失败: %v", err) continue } size, _ := policy.Size(ctx) fmt.Printf("添加 %s,当前大小: %d\n", key, size) } // key4的添加会触发自动淘汰 // 检查哪些键还存在 for _, key := range keys { has, _ := policy.Has(ctx, key) fmt.Printf("%s 是否存在: %v\n", key, has) } } ``` -------------------------------- ### Go Distributed Lock Service Example Source: https://github.com/justinwongcn/hamster/blob/main/docs/USER_GUIDE.md This Go example demonstrates Hamster's distributed lock service. It shows how to acquire a lock with a specified key, expiration, timeout, and retry strategy, perform business logic, and then release the lock, ensuring concurrent access control in a distributed environment. ```go package main import ( "context" "fmt" "log" "time" "github.com/justinwongcn/hamster/internal/application/lock" "github.com/justinwongcn/hamster/internal/infrastructure/lock" ) func main() { // 创建分布式锁服务 distributedLock := lock.NewMemoryDistributedLock() service := lock.NewDistributedLockApplicationService(distributedLock) ctx := context.Background() // 获取锁 lockCmd := lock.LockCommand{ Key: "resource:123", Expiration: 30 * time.Second, Timeout: 5 * time.Second, RetryType: "exponential", RetryCount: 3, RetryBase: 100 * time.Millisecond, } result, err := service.Lock(ctx, lockCmd) if err != nil { log.Fatal(err) } fmt.Printf("成功获取锁: %s\n", result.Key) // 执行业务逻辑 time.Sleep(2 * time.Second) // 释放锁 unlockCmd := lock.UnlockCommand{Key: "resource:123"} if err := service.Unlock(ctx, unlockCmd); err != nil { log.Fatal(err) } fmt.Println("锁已释放") } ``` -------------------------------- ### Go Example: Initialize LRUPolicy Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/lru_policy.md Illustrates how to instantiate the `LRUPolicy` using `NewLRUPolicy`, demonstrating both unlimited capacity and a specific capacity limit. ```Go // 无限制容量 policy := NewLRUPolicy() // 限制容量为100 policy := NewLRUPolicy(100) ``` -------------------------------- ### Select Nodes and Get Statistics from Hamster Consistent Hash Service Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This Go example shows how to select a single peer or multiple peers (for replication) based on a given key using the Hamster consistent hash service. It also demonstrates how to retrieve service statistics like total peers and virtual nodes, useful for monitoring and debugging. ```go // 选择单个节点 peer, err := hashService.SelectPeer(ctx, "user:123") fmt.Printf("键 user:123 -> 节点 %s (%s)\n", peer.ID, peer.Address) // 选择多个节点(用于副本) peers, err := hashService.SelectPeers(ctx, "user:123", 3) // 获取统计信息 stats, err := hashService.GetStats(ctx) fmt.Printf("总节点: %d, 虚拟节点: %d\n", stats.TotalPeers, stats.VirtualNodes) ``` -------------------------------- ### Best Practice: Optimizing Configuration Parameters Source: https://github.com/justinwongcn/hamster/blob/main/docs/API.md Provides examples of configuring components like Bloom filters and consistent hash maps based on business requirements to balance performance, memory usage, and load distribution. ```Go // ✅ 正确:根据业务需求配置参数 config, err := NewBloomFilterConfig( expectedElements, // 根据实际数据量设置 0.01, // 1%假阳性率,平衡内存和准确性 ) hashMap := NewConsistentHashMap( 150, // 虚拟节点数,提升负载均衡 nil, // 使用默认哈希函数 ) ``` -------------------------------- ### Perform Basic Hamster Cache Operations (Set, Get, Delete, LoadAndDelete, Stats) Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This Go example covers fundamental operations for the Hamster cache service, including setting, retrieving, deleting, and atomically loading and deleting entries. It also demonstrates how to fetch cache statistics like hit rate, providing insights into cache performance. ```go ctx := context.Background() // 设置缓存 err := cacheService.Set(ctx, "user:123", userData, time.Hour) // 获取缓存 value, err := cacheService.Get(ctx, "user:123") // 删除缓存 err := cacheService.Delete(ctx, "user:123") // 获取并删除 value, err := cacheService.LoadAndDelete(ctx, "user:123") // 获取统计信息 stats, err := cacheService.Stats(ctx) fmt.Printf("命中率: %.2f%%\n", stats.HitRate*100) ``` -------------------------------- ### Install Hamster Go Module Source: https://github.com/justinwongcn/hamster/blob/main/README.md Installs the Hamster distributed system toolkit as a Go module using the `go get` command. This command fetches the latest version of the Hamster library and its dependencies. ```bash go get github.com/justinwongcn/hamster ``` -------------------------------- ### Consistent Hashing Module Usage Example Source: https://github.com/justinwongcn/hamster/blob/main/docs/USER_GUIDE.md Demonstrates the initialization of the consistent hashing module, adding peers, and selecting nodes based on a key. Illustrates a typical workflow for integrating the consistent hashing functionality within a Go application. ```go // 创建配置 config, err := domain.NewVirtualNodeConfig(150, nil) if err != nil { log.Fatal(err) } // 创建一致性哈希实例 ch := infrastructure.NewConsistentHashImpl(config) peerPicker := infrastructure.NewConsistentHashPeerPicker(ch) service := application.NewConsistentHashApplicationService(peerPicker) // 添加节点 peers := []application.PeerRequest{ {ID: "node1", Address: "192.168.1.1:8080", Weight: 100}, {ID: "node2", Address: "192.168.1.2:8080", Weight: 150}, {ID: "node3", Address: "192.168.1.3:8080", Weight: 200}, } cmd := application.AddPeersCommand{Peers: peers} if err := service.AddPeers(ctx, cmd); err != nil { log.Fatal(err) } // 选择节点处理请求 for i := 0; i < 100; i++ { key := fmt.Sprintf("request:%d", i) result, err := service.SelectPeer(ctx, application.PeerSelectionCommand{Key: key}) if err != nil { log.Printf("选择节点失败: %v", err) continue } fmt.Printf("请求 %s 路由到节点 %s\n", key, result.Peer.ID) } ``` -------------------------------- ### Go MaxMemoryCache Unit Test Example Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/README.md Provides an example of a unit test for the MaxMemoryCache. It defines test cases with various operations (set, get, delete) and asserts the cache's behavior and final size, demonstrating a table-driven testing approach. ```go func TestMaxMemoryCache(t *testing.T) { tests := []struct { name string maxSize int64 ops []operation wantSize int64 }{ { name: "基本操作", maxSize: 1024, ops: []operation{ {op: "set", key: "key1", value: "value1"}, {op: "get", key: "key1", want: "value1"}, {op: "delete", key: "key1"}, {op: "get", key: "key1", wantErr: true}, }, wantSize: 0, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cache := NewMaxMemoryCache(tt.maxSize) executeOperations(t, cache, tt.ops) assert.Equal(t, tt.wantSize, cache.Size()) }) } } ``` -------------------------------- ### Go Hamster Basic Cache Service Usage Example Source: https://github.com/justinwongcn/hamster/blob/main/REFACTOR_SUMMARY.md This Go example illustrates the fundamental operations of the Hamster cache service. It covers initializing the cache with specific options, setting a key-value pair with an expiration, retrieving the stored value, and finally deleting the entry. This snippet demonstrates the Set, Get, and Delete methods. ```go package main import ( "context" "time" "github.com/justinwongcn/hamster" "github.com/justinwongcn/hamster/cache" ) func main() { // 创建缓存服务 cacheService, err := hamster.NewCache( cache.WithMaxMemory(1024*1024), cache.WithEvictionPolicy("lru"), ) if err != nil { panic(err) } ctx := context.Background() // 使用缓存 err = cacheService.Set(ctx, "key", "value", time.Hour) value, err := cacheService.Get(ctx, "key") err = cacheService.Delete(ctx, "key") } ``` -------------------------------- ### Go Cache Thread Safety with RWMutex for Get Operations Source: https://github.com/justinwongcn/hamster/blob/main/internal/interfaces/types.md This example illustrates how to ensure thread safety for a cache's `Get` method in Go using `sync.RWMutex`. It demonstrates acquiring a read lock (`RLock`) before accessing shared data and releasing it (`RUnlock`) using `defer`, preventing race conditions during concurrent reads. ```Go // ✅ 推荐:确保线程安全 type MyCache struct { mu sync.RWMutex data map[string]any } func (c *MyCache) Get(ctx context.Context, key string) (any, error) { c.mu.RLock() defer c.mu.RUnlock() value, exists := c.data[key] if !exists { return nil, ErrKeyNotFound } return value, nil } ``` -------------------------------- ### Basic Usage of Consistent Hash and Peer Picker Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/consistent_hash/README.md A foundational example demonstrating how to initialize ConsistentHashMap and SingleflightPeerPicker, add peers, and select a peer based on a key. ```Go import "github.com/justinwongcn/hamster/internal/infrastructure/consistent_hash" // 创建一致性哈希映射 hashMap := consistent_hash.NewConsistentHashMap(150, nil) // 150个虚拟节点 // 创建节点选择器 picker := consistent_hash.NewSingleflightPeerPicker(hashMap) // 添加节点 peer1, _ := domain.NewPeerInfo("server1", "192.168.1.1:8080", 100) peer2, _ := domain.NewPeerInfo("server2", "192.168.1.2:8080", 100) picker.AddPeers(peer1, peer2) // 选择节点 peer, err := picker.PickPeer("user:12345") if err != nil { log.Printf("选择节点失败: %v", err) return } fmt.Printf("选择的节点: %s (%s)\n", peer.ID(), peer.Address()) ``` -------------------------------- ### Implement Custom Cache Repository in Go Source: https://github.com/justinwongcn/hamster/blob/main/internal/domain/cache/README.md Provides an example of defining and implementing a custom cache repository interface with `Get` and `Set` methods, illustrating how to extend the caching mechanism. ```Go type MyCustomRepository struct { // 内部存储 } func (r *MyCustomRepository) Get(ctx context.Context, key string) (any, error) { // 实现获取逻辑 return nil, nil } func (r *MyCustomRepository) Set(ctx context.Context, key string, val any, expiration time.Duration) error { // 实现设置逻辑 return nil } // 实现其他必需方法... ``` -------------------------------- ### Retrieve Hamster Library Version Source: https://github.com/justinwongcn/hamster/blob/main/PUBLIC_API.md This Go snippet shows how to get the current version string of the Hamster library using `hamster.GetVersion()`. This is useful for logging, debugging, or ensuring compatibility. ```go version := hamster.GetVersion() fmt.Printf("当前版本: %s\n", version) ``` -------------------------------- ### Go: Advanced Cache Configuration and Eviction Source: https://github.com/justinwongcn/hamster/blob/main/EXAMPLES.md This snippet illustrates how to initialize a cache service with detailed configurations such as maximum memory, default expiration, cleanup intervals, and an LRU eviction policy. It also demonstrates enabling a Bloom filter for efficient key existence checks and setting up a callback function to handle cache item evictions, testing with a large dataset to trigger the eviction mechanism. ```Go func advancedCacheExample() { // 使用配置结构体创建缓存 config := &cache.Config{ MaxMemory: 2 * 1024 * 1024, // 2MB DefaultExpiration: 30 * time.Minute, CleanupInterval: 5 * time.Minute, EvictionPolicy: "lru", EnableBloomFilter: true, BloomFilterFalsePositiveRate: 0.01, } cacheService, err := cache.NewServiceWithConfig(config) if err != nil { log.Fatalf("创建缓存服务失败: %v", err) } ctx := context.Background() // 设置淘汰回调函数 cacheService.OnEvicted(func(key string, val any) { fmt.Printf("缓存项被淘汰: key=%s, value=%v\n", key, val) }) // 测试大量数据,触发淘汰 for i := 0; i < 1000; i++ { key := fmt.Sprintf("key_%d", i) value := fmt.Sprintf("large_value_%d_%s", i, string(make([]byte, 1024))) // 1KB 数据 err := cacheService.Set(ctx, key, value, time.Hour) if err != nil { log.Printf("设置缓存失败: %v", err) } } fmt.Println("✓ 大量数据写入完成") } ``` -------------------------------- ### Retrieve Cache Entry with Get Method in Go Source: https://github.com/justinwongcn/hamster/blob/main/internal/infrastructure/cache/max_memory_cache.md Implements the `Get` method for MaxMemoryCache, responsible for retrieving a value by key. Its logic includes validating the key, acquiring a read lock, finding the entry, checking for expiration, updating LRU and access time, and updating statistics. An example demonstrates its usage and error handling for a missing key. ```Go func (c *MaxMemoryCache) Get(ctx context.Context, key string) (any, error) // Example: value, err := cache.Get(ctx, "user:123") if err != nil { if errors.Is(err, ErrKeyNotFound) { // 处理键不存在 } return err } ```