### Initialize and Start a TCPServer Source: https://github.com/cyberinferno/go-utils/blob/master/docs/tcpserver.md Demonstrates how to configure and start a new TCPServer instance. It requires dependencies like a logger, ID generator, and a session factory function. ```go import ( "github.com/cyberinferno/go-utils/idgenerator" "github.com/cyberinferno/go-utils/logger" "github.com/cyberinferno/go-utils/safemap" "github.com/cyberinferno/go-utils/tcpserver" ) log := logger.New(...) // your logger srv := &tcpserver.TCPServer{ Logger: log, Name: "myserver", Addr: ":8080", Sessions: safemap.NewSafeMap[uint32, tcpserver.TCPServerSession](), NewSession: myNewSession, IdGenerator: idgenerator.NewIdGenerator(0), } if err := srv.Start(); err != nil { log.Fatal("start failed", err) } defer srv.Stop() ``` -------------------------------- ### Go Performance Monitor API: Start Method Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Details the `Start` method of the `PerformanceMonitor`. It records the current time as the start time and can be called multiple times, overwriting the previous start time without affecting the end time. ```go func (p *PerformanceMonitor) Start() // Behavior: // - Sets the start time to the current time // - Can be called multiple times (overwrites previous start time) // - Does not affect the end time ``` -------------------------------- ### Complete Concurrent Example Source: https://github.com/cyberinferno/go-utils/blob/master/docs/idgenerator.md A full implementation example showing the lifecycle of an IdGenerator in a concurrent environment, including thread-safe collection of generated IDs. ```go package main import ( "fmt" "sync" "github.com/cyberinferno/go-utils/idgenerator" ) func main() { gen := idgenerator.NewIdGenerator(0) var wg sync.WaitGroup mu := sync.Mutex{} var seen []uint32 for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() id := gen.Id() mu.Lock() seen = append(seen, id) mu.Unlock() }() } wg.Wait() fmt.Println(seen) } ``` -------------------------------- ### Complete Example: In-Process Cache Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safemap.md A full example demonstrating the creation and basic usage of a SafeMap as an in-process cache. It shows storing, retrieving, deleting, and checking the size of the cache. ```go package main import ( "fmt" "github.com/cyberinferno/go-utils/safemap" ) func main() { cache := safemap.NewSafeMap[string, string]() cache.Store("user:1", "Alice") cache.Store("user:2", "Bob") if v, ok := cache.Get("user:1"); ok { fmt.Println("user:1 =>", v) } cache.Delete("user:2") fmt.Println("entries:", cache.Len()) } ``` -------------------------------- ### Handle Performance Monitor Edge Cases in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Illustrates how the monitor behaves when methods are called out of sequence, such as stopping before starting or calling start/stop multiple times. These examples clarify the internal state management and safety guarantees of the utility. ```go // Multiple Start Calls pm := perfmonitor.NewPerformanceMonitor() pm.Start() time.Sleep(10 * time.Millisecond) pm.Start() // Resets start time pm.Stop() // Multiple Stop Calls pm.Start() time.Sleep(10 * time.Millisecond) pm.Stop() firstElapsed := pm.ElapsedMilliseconds() time.Sleep(10 * time.Millisecond) pm.Stop() // Updates end time ``` -------------------------------- ### Install Event-Driven TCP Client Package Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md This snippet shows how to import the event-driven TCP client package into your Go project. Ensure you have the correct path for the package. ```go import "github.com/cyberinferno/go-utils/eventdriventcpclient" ``` -------------------------------- ### Length-Prefixed Messages TCP Client Example - Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Shows how to handle length-prefixed messages with the TCP client by setting `DataLengthBasedRead` to true. The example demonstrates sending a message prefixed with its length (as a 4-byte uint32 in little-endian format) and receiving it. ```go package main import ( "encoding/binary" "log" "time" "github.com/cyberinferno/go-utils/eventdriventcpclient" ) func main() { cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:9000") cfg.DataLengthBasedRead = true client := eventdriventcpclient.NewEventDrivenTCPClient(cfg) defer client.Close() client.OnDataReceived(func(ev eventdriventcpclient.DataReceivedEvent) { log.Printf("message: %q", string(ev.Data)) }) if err := client.Connect(); err != nil { log.Fatal(err) } // Send a length-prefixed message msg := []byte("hello") buf := make([]byte, 4+len(msg)) binary.LittleEndian.PutUint32(buf[:4], uint32(len(msg))) copy(buf[4:], msg) _ = client.Send(buf) time.Sleep(time.Second) } ``` -------------------------------- ### Complete Go Performance Monitoring Example Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md A full Go program demonstrating how to use the perfmonitor package to time a simulated operation (time.Sleep). It includes necessary imports and prints the elapsed time. ```go package main import ( "fmt" "time" "github.com/cyberinferno/go-utils/perfmonitor" ) func main() { pm := perfmonitor.NewPerformanceMonitor() pm.Start() time.Sleep(100 * time.Millisecond) // Simulate work pm.Stop() elapsed := pm.ElapsedMilliseconds() fmt.Printf("Operation completed in %.2f ms\n", elapsed) // Output: Operation completed in ~100.00 ms } ``` -------------------------------- ### Install safemap Package Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safemap.md This snippet shows how to import the safemap package into your Go project. Ensure you have the correct path to the package. ```go import "github.com/cyberinferno/go-utils/safemap" ``` -------------------------------- ### Initialize and Use IdGenerator in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/idgenerator.md Demonstrates how to instantiate an IdGenerator with a starting value and retrieve sequential IDs. The generator is safe for concurrent use across multiple goroutines. ```go gen := idgenerator.NewIdGenerator(0) first := gen.Id() // 1 second := gen.Id() // 2 third := gen.Id() // 3 ``` -------------------------------- ### Measure Database Query Time in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Demonstrates timing a database query. The `Start()` and `Stop()` methods are called before and after the database operation, and the elapsed time is logged. ```go package main import ( "fmt" "log" "github.com/cyberinferno/go-utils/perfmonitor" // Assume db and User are defined elsewhere // var db *sql.DB // type User struct { ... } ) func fetchUser(userID string) (*User, error) { pm := perfmonitor.NewPerformanceMonitor() pm.Start() // Assume db.Query is a placeholder for an actual database query user, err := db.Query("SELECT * FROM users WHERE id = ?", userID) pm.Stop() if err != nil { return nil, err } elapsed := pm.ElapsedMilliseconds() log.Printf("Database query took %.2f ms", elapsed) return user, nil } ``` -------------------------------- ### Manage Server Lifecycle Source: https://github.com/cyberinferno/go-utils/blob/master/docs/tcpserver.md Provides methods to start the server listener and perform a graceful shutdown of all active sessions. ```go // Starting the server if err := srv.Start(); err != nil { // server already running or listen failed } // Stopping the server srv.Stop() ``` -------------------------------- ### Simple Echo Client Example - Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Demonstrates a basic TCP client that connects to a server, registers event handlers for connection state, data received, and errors, sends a message, and then disconnects. It uses the `eventdriventcpclient` package. ```go package main import ( "log" "time" "github.com/cyberinferno/go-utils/eventdriventcpclient" ) func main() { cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:8080") client := eventdriventcpclient.NewEventDrivenTCPClient(cfg) defer client.Close() client.OnConnectionState(func(ev eventdriventcpclient.ConnectionStateEvent) { log.Printf("state: %s", ev.State) }) client.OnDataReceived(func(ev eventdriventcpclient.DataReceivedEvent) { log.Printf("received %d bytes: %s", ev.Length, string(ev.Data)) }) client.OnError(func(ev eventdriventcpclient.ErrorEvent) { log.Printf("error: %v", ev.Error) }) if err := client.Connect(); err != nil { log.Fatal(err) } _ = client.Send([]byte("hello\n")) time.Sleep(time.Second) _ = client.Disconnect() } ``` -------------------------------- ### Implement TCPServerSession Interface Source: https://github.com/cyberinferno/go-utils/blob/master/docs/tcpserver.md A complete example demonstrating how to implement the TCPServerSession interface to create an echo server. It includes logic for reading from and writing to the connection, as well as managing the session lifecycle. ```go type EchoSession struct { id uint32 conn net.Conn server *tcpserver.TCPServer closed sync.Once } func (e *EchoSession) ID() uint32 { return e.id } func (e *EchoSession) Handle() { defer e.server.RemoveSession(e.id) buf := make([]byte, 4096) for { n, err := e.conn.Read(buf) if err != nil { return } if _, err := e.conn.Write(buf[:n]); err != nil { return } } } func (e *EchoSession) Close() error { var err error e.closed.Do(func() { err = e.conn.Close() }) return err } func (e *EchoSession) Send(data []byte) error { _, err := e.conn.Write(data) return err } ``` -------------------------------- ### Measure and Reset Performance Monitor in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Demonstrates how to initialize, start, stop, and reset the performance monitor to track multiple distinct operations sequentially. This pattern is useful for comparing different function implementations or measuring discrete blocks of code. ```go pm := perfmonitor.NewPerformanceMonitor() // First measurement pm.Start() operation1() pm.Stop() elapsed1 := pm.ElapsedMilliseconds() // Reset and reuse pm.Reset() // Second measurement pm.Start() operation2() pm.Stop() elapsed2 := pm.ElapsedMilliseconds() fmt.Printf("Operation 1: %.2f ms, Operation 2: %.2f ms\n", elapsed1, elapsed2) ``` -------------------------------- ### Auto-Reconnect TCP Client Example - Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Illustrates how to configure the TCP client for automatic reconnection. It sets `AutoReconnect` to true and specifies a `ReconnectInterval`. The client will attempt to reconnect if the connection is lost. This example keeps the client running for a duration to observe reconnection behavior. ```go package main import ( "log" "time" "github.com/cyberinferno/go-utils/eventdriventcpclient" ) func main() { cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:8080") cfg.AutoReconnect = true cfg.ReconnectInterval = 2 * time.Second client := eventdriventcpclient.NewEventDrivenTCPClient(cfg) defer client.Close() client.OnConnectionState(func(ev eventdriventcpclient.ConnectionStateEvent) { log.Printf("state: %s (err: %v)", ev.State, ev.Error) }) client.OnDataReceived(func(ev eventdriventcpclient.DataReceivedEvent) { log.Printf("received %d bytes", ev.Length) }) client.OnError(func(ev eventdriventcpclient.ErrorEvent) { log.Printf("error: %v", ev.Error) }) if err := client.Connect(); err != nil { log.Fatal(err) } // If the connection drops, the client will reconnect automatically. time.Sleep(60 * time.Second) } ``` -------------------------------- ### Install Go Performance Monitor Package Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md This snippet shows the import statement required to include the perfmonitor package in your Go project. It assumes you are using Go modules. ```go import "github.com/cyberinferno/go-utils/perfmonitor" ``` -------------------------------- ### Configuring TTL Values for Cache Entries Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Provides best practice examples for setting Time-To-Live (TTL) values based on the volatility of the data being cached. ```go // Frequently changing data - short TTL cacher.GetOrFetch(ctx, "rate:USD", 1*time.Minute, fetchRate) // Moderately changing data - medium TTL cacher.GetOrFetch(ctx, "user:123", time.Hour, fetchUser) // Rarely changing data - long TTL cacher.GetOrFetch(ctx, "config:app", 24*time.Hour, fetchConfig) ``` -------------------------------- ### Manage Cache Entries Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Provides examples for cache maintenance, specifically deleting keys and setting appropriate TTL values for different data freshness requirements. ```go // Delete a specific cache key cacher.Delete("user:123") // Set TTL for different durations data, err := cacher.GetOrFetch(ctx, "key", 5*time.Minute, fetchFn) data, err := cacher.GetOrFetch(ctx, "key", time.Hour, fetchFn) data, err := cacher.GetOrFetch(ctx, "key", 24*time.Hour, fetchFn) ``` -------------------------------- ### Measure Function Execution Time in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md An example showing how to measure the execution time of a function using `defer` with `pm.Stop()`. This ensures that `Stop()` is called even if the function panics or returns early. ```go package main import ( "fmt" "github.com/cyberinferno/go-utils/perfmonitor" ) func processData(data []int) error { pm := perfmonitor.NewPerformanceMonitor() pm.Start() defer pm.Stop() // Process data for _, item := range data { // ... processing logic } elapsed := pm.ElapsedMilliseconds() fmt.Printf("Processed %d items in %.2f ms\n", len(data), elapsed) return nil } ``` -------------------------------- ### Monitor Database Query Performance in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md A practical example of wrapping a database query with the performance monitor to log execution time and handle potential errors. This pattern helps in identifying slow queries in production environments. ```go func (s *DBService) QueryUsers() ([]User, error) { pm := perfmonitor.NewPerformanceMonitor() pm.Start() rows, err := s.db.Query("SELECT * FROM users") pm.Stop() elapsed := pm.ElapsedMilliseconds() if err != nil { log.Printf("Query failed after %.2f ms: %v", elapsed, err) return nil, err } log.Printf("Query completed in %.2f ms", elapsed) defer rows.Close() return users, nil } ``` -------------------------------- ### Go Performance Monitor API: NewPerformanceMonitor Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Documentation for the `NewPerformanceMonitor` function. It explains that this function creates and returns a new `PerformanceMonitor` instance, initialized with zero start and end times. ```go func NewPerformanceMonitor() *PerformanceMonitor // Returns: A new PerformanceMonitor instance with zero start and end times. ``` -------------------------------- ### Measure HTTP Request Duration in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Shows how to measure the duration of an HTTP request. The `Start()` and `Stop()` methods bracket the `http.Get` call, and the elapsed time is logged, including in case of errors. ```go package main import ( "fmt" "log" "net/http" "github.com/cyberinferno/go-utils/perfmonitor" ) // Assume Response is defined elsewhere // type Response struct { ... } func makeAPICall(url string) (*Response, error) { pm := perfmonitor.NewPerformanceMonitor() pm.Start() resp, err := http.Get(url) pm.Stop() elapsed := pm.ElapsedMilliseconds() if err != nil { log.Printf("API call failed after %.2f ms: %v", elapsed, err) return nil, err } log.Printf("API call completed in %.2f ms", elapsed) return resp, nil } ``` -------------------------------- ### API Response Caching with Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Illustrates caching API responses using the go-utils cacher and Redis. This example fetches product data from an external API and caches the response to improve performance. It handles HTTP requests, response parsing, and error handling. Dependencies include 'context', 'encoding/json', 'fmt', 'io', 'log', 'net/http', 'time', 'github.com/cyberinferno/go-utils/cacher', and 'github.com/redis/go-redis/v9'. ```go package main import ( "context" "encoding/json" "fmt" "io" "log" "net/http" "time" "github.com/cyberinferno/go-utils/cacher" "github.com/redis/go-redis/v9" ) type Product struct { ID int `json:"id"` Name string `json:"name"` Price float64 `json:"price"` Description string `json:"description"` } type ProductService struct { cacher cacher.Cacher[Product] apiURL string ctx context.Context } func NewProductService(redisClient *redis.Client, apiURL string) *ProductService { return &ProductService{ cacher: cacher.NewRedisCacher[Product](redisClient), apiURL: apiURL, ctx: context.Background(), } } func (s *ProductService) GetProduct(productID int) (Product, error) { key := fmt.Sprintf("product:%d", productID) fetchProduct := func(ctx context.Context) (Product, error) { url := fmt.Sprintf("%s/products/%d", s.apiURL, productID) req, err := http.NewRequestWithContext(ctx, "GET", url, nil) if err != nil { return Product{}, err } client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { return Product{}, err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return Product{}, fmt.Errorf("API returned status %d", resp.StatusCode) } body, err := io.ReadAll(resp.Body) if err != nil { return Product{}, err } var product Product if err := json.Unmarshal(body, &product); err != nil { return Product{}, err } return product, nil } // Cache API responses for 15 minutes return s.cacher.GetOrFetch(s.ctx, key, 15*time.Minute, fetchProduct) } func main() { redisClient := redis.NewClient(&redis.Options{ Addr: "localhost:6379", }) service := NewProductService(redisClient, "https://api.example.com") product, err := service.GetProduct(123) if err != nil { log.Fatalf("Failed to get product: %v", err) } fmt.Printf("Product: %+v\n", product) } ``` -------------------------------- ### SafeMap Concurrency Example Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safemap.md Illustrates the concurrent safety of SafeMap by having multiple goroutines store data simultaneously. It uses `sync.WaitGroup` to ensure all goroutines complete before checking the map's size. ```go var wg sync.WaitGroup m := safemap.NewSafeMap[int, int]() for i := range 100 { wg.Add(1) go func(k int) { defer wg.Done() m.Store(k, k*2) }(i) } wg.Wait() fmt.Println(m.Len()) // 100 ``` -------------------------------- ### Track Execution Time with PerformanceMonitor in Go Source: https://context7.com/cyberinferno/go-utils/llms.txt The perfmonitor package allows for simple elapsed time measurement for performance profiling. It provides methods to start, stop, and reset the timer, and to retrieve the elapsed time in milliseconds. This is useful for identifying performance bottlenecks in Go applications. ```go package main import ( "fmt" "time" "github.com/cyberinferno/go-utils/perfmonitor" ) func main() { pm := perfmonitor.NewPerformanceMonitor() // Measure operation time pm.Start() time.Sleep(150 * time.Millisecond) // Simulated work pm.Stop() fmt.Printf("Operation took %.2f ms\n", pm.ElapsedMilliseconds()) // Output: Operation took 150.XX ms // Reset for reuse pm.Reset() pm.Start() time.Sleep(50 * time.Millisecond) pm.Stop() fmt.Printf("Second operation: %.2f ms\n", pm.ElapsedMilliseconds()) // Output: Second operation: 50.XX ms } ``` -------------------------------- ### Utilize Helper Functions for Arrays, Strings, Bytes, JSON, and Time in Go Source: https://context7.com/cyberinferno/go-utils/llms.txt The utils package offers a collection of common helper functions. These include getting random elements from slices, generating random strings, reading/writing byte buffers, joining byte slices, converting booleans to 'Yes'/'No', validating JSON strings, creating pointers, and performing time conversions between GMT/UTC and IST. It also includes a utility for sending Discord notifications. ```go package main import ( "fmt" "github.com/cyberinferno/go-utils/utils" ) func main() { // Get random element from slice fruits := []string{"apple", "banana", "cherry", "date"} random := utils.GetRandomElement(fruits) fmt.Printf("Random fruit: %s\n", random) // Generate random alphanumeric string token := utils.GenerateRandomString(16) fmt.Printf("Random token: %s\n", token) // Output: Random token: aB3xK9mNpQ2wR5tY // Read null-terminated string from bytes buffer := []byte{'H', 'e', 'l', 'l', 'o', 0, 'X', 'Y', 'Z'} str := utils.ReadStringFromBytes(buffer) fmt.Printf("String: %s\n", str) // Output: String: Hello // Create fixed-length byte buffer from string fixedBytes := utils.MakeFixedLengthStringBytes("Hi", 10) fmt.Printf("Fixed bytes: %v (len=%d)\n", fixedBytes, len(fixedBytes)) // Output: Fixed bytes: [72 105 0 0 0 0 0 0 0 0] (len=10) // Join byte slices joined := utils.JoinBytes([]byte{1, 2}, []byte{3, 4}, []byte{5}) fmt.Printf("Joined: %v\n", joined) // Output: Joined: [1 2 3 4 5] // Boolean to Yes/No fmt.Printf("Active: %s\n", utils.BoolToYesNo(true)) // Output: Active: Yes // Validate JSON object string fmt.Printf("Is valid JSON: %v\n", utils.IsJsonString(`{"key": "value"}`)) // Output: Is valid JSON: true // Convert pointer (useful for optional fields) name := utils.Pointer("John") fmt.Printf("Name pointer: %v\n", *name) // Output: Name pointer: John // Time conversion (GMT/UTC to IST) istTime, _ := utils.ConvertGMTtoIST("2024-01-15 10:30:00") fmt.Printf("IST time: %s\n", istTime) // Output: IST time: 2024-01-15 16:00:00 utcIst, _ := utils.ConvertUTCtoIST("2024-01-15T10:30:00Z") fmt.Printf("UTC to IST: %s\n", utcIst) // Output: UTC to IST: 2024-01-15 16:00:00 // Send Discord notification (async, errors ignored) utils.SendDiscordNotification( "https://discord.com/api/webhooks/...", "Server started successfully!", ) } ``` -------------------------------- ### Measure Operation Duration in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Illustrates the basic usage pattern for measuring the duration of an operation using the PerformanceMonitor. It involves starting the monitor, performing the operation, stopping the monitor, and then retrieving the elapsed time. ```go import "github.com/cyberinferno/go-utils/perfmonitor" import "fmt" // Assume doSomeWork() is a function that performs the operation // func doSomeWork() { ... } pm := perfmonitor.NewPerformanceMonitor() // Start timing pm.Start() // Perform some operation doSomeWork() // Stop timing pm.Stop() // Get elapsed time in milliseconds elapsed := pm.ElapsedMilliseconds() fmt.Printf("Operation took %.2f ms\n", elapsed) ``` -------------------------------- ### In-Memory Cache Implementation with Singleflight (Go) Source: https://context7.com/cyberinferno/go-utils/llms.txt Illustrates the use of the in-memory generic cacher, suitable for single-process applications or testing. It utilizes go-cache and singleflight for cache stampede prevention. The example shows creating a cacher with custom expiration and cleanup intervals, fetching data, and checking item counts. ```go package main import ( "context" "fmt" "time" "github.com/cyberinferno/go-utils/cacher" ) type Config struct { APIKey string `json:"api_key"` RateLimit int `json:"rate_limit"` } func main() { // Create memory cacher with 5-minute default expiration and 10-minute cleanup configCacher := cacher.NewMemoryCacher[Config](5*time.Minute, 10*time.Minute) ctx := context.Background() fetchConfig := func(ctx context.Context) (Config, error) { return Config{APIKey: "secret-key", RateLimit: 100}, nil } // First call fetches, subsequent calls return cached value config, _ := configCacher.GetOrFetch(ctx, "app:config", time.Hour, fetchConfig) fmt.Printf("Config: %+v\n", config) // Output: Config: {APIKey:secret-key RateLimit:100} // Cache management count, _ := configCacher.ItemCount(ctx) fmt.Printf("Items in cache: %d\n", count) // Output: Items in cache: 1 } ``` -------------------------------- ### Error Handling: Redis Connection Errors (Go) Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Shows how Redis-specific errors might be wrapped and returned by the cacher. This example highlights that errors from Redis operations, unmarshaling, or connection issues can be encountered when interacting with the Redis cacher. ```go user, err := cacher.GetOrFetch(ctx, "user:1", ttl, fetchFn) if err != nil { // May contain Redis connection errors, unmarshaling errors, etc. log.Printf("Error: %v", err) } ``` -------------------------------- ### Create Go Performance Monitor Instance Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Demonstrates how to create a new instance of the PerformanceMonitor. The monitor is initialized and ready for use immediately after creation. ```go import "github.com/cyberinferno/go-utils/perfmonitor" pm := perfmonitor.NewPerformanceMonitor() ``` -------------------------------- ### Registering Event Handlers and Connecting Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Demonstrates the recommended pattern of registering event handlers before initiating a connection to ensure all lifecycle events are captured. ```go client.OnConnectionState(func(e ConnectionStateEvent) { fmt.Printf("State changed to: %v\n", e.State) }) client.OnDataReceived(func(e DataReceivedEvent) { // Copy data if needed for async processing data := make([]byte, len(e.Data)) copy(data, e.Data) go processData(data) }) err := client.Connect() if err != nil { log.Fatal(err) } defer client.Close() ``` -------------------------------- ### Configure and Test Redis Client Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Demonstrates how to initialize a Redis client with connection pooling and verify connectivity using the Ping command. ```go redisClient := redis.NewClient(&redis.Options{ Addr: "localhost:6379", PoolSize: 20, MinIdleConns: 5, MaxRetries: 3, }) if err := redisClient.Ping(context.Background()).Err(); err != nil { log.Fatalf("Failed to connect to Redis: %v", err) } ``` -------------------------------- ### Initialize and Close Logger Source: https://github.com/cyberinferno/go-utils/blob/master/docs/logger.md Demonstrates how to instantiate a file-based logger and ensure resources are released using defer. ```go logDir := os.Getenv("LOG_DIR") if logDir == "" { logDir = "./logs" } log := logger.NewZerologFileLogger("my-service", logDir, zerolog.InfoLevel) defer log.Close() ``` -------------------------------- ### Go Performance Monitor API: ElapsedMilliseconds Method Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Documents the `ElapsedMilliseconds` method, which returns the time difference between `Start()` and `Stop()` in milliseconds as a float64. It handles cases where `Start()` or `Stop()` were not called, returning 0.0. ```go func (p *PerformanceMonitor) ElapsedMilliseconds() float64 // Returns: // - Elapsed time in milliseconds as a float64 // - Returns 0.0 if Start() was not called // - Returns 0.0 if Stop() was not called // - Returns 0.0 if both times are zero (after Reset()) // Precision: The function uses microseconds internally and converts to milliseconds, providing sub-millisecond precision. ``` -------------------------------- ### Initialize Redis Cacher Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Demonstrates how to instantiate a Redis-backed cacher using the go-redis client. This implementation is suitable for distributed systems requiring shared cache state. ```go redisClient := redis.NewClient(&redis.Options{ Addr: "localhost:6379", Password: "", DB: 0, }) stringCacher := cacher.NewRedisCacher[string](redisClient) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } userCacher := cacher.NewRedisCacher[User](redisClient) ``` -------------------------------- ### Go Performance Monitor API: Reset Method Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Describes the `Reset` method, which clears both the start and end times of the `PerformanceMonitor`. This allows the monitor instance to be reused for subsequent measurements. After reset, `ElapsedMilliseconds()` returns 0.0 until new start and stop times are recorded. ```go func (p *PerformanceMonitor) Reset() // Behavior: // - Sets both start and end times to zero // - Safe to call multiple times // - After reset, ElapsedMilliseconds() returns 0.0 until Start() and Stop() are called again ``` -------------------------------- ### Get Cache Item Count in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Retrieves the total number of items currently stored in the cache. ```go // Get the number of cached items count := cacher.ItemCount() fmt.Printf("Cache contains %d items\n", count) ``` -------------------------------- ### Create a New Event-Driven TCP Client Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md This code snippet illustrates the creation of a new instance of the event-driven TCP client using a provided configuration. It also shows how to ensure the client is properly closed when it's no longer needed. ```go cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:9000") client := eventdriventcpclient.NewEventDrivenTCPClient(cfg) defer client.Close() ``` -------------------------------- ### Logger Usage Patterns Source: https://github.com/cyberinferno/go-utils/blob/master/docs/logger.md Common implementation patterns including service initialization, request-scoped logging with context, and component-based logging. ```go // Service Initialization log := logger.NewZerologFileLogger("my-api", "./logs", zerolog.InfoLevel) defer log.Close() // Request-Scoped Logger reqLog := h.log.With(logger.Field{Key: "request_id", Value: requestID}) reqLog.Info("request started") // Component Logger type Worker struct { log logger.Logger } func NewWorker(parent logger.Logger, name string) *Worker { return &Worker{log: parent.With(logger.Field{Key: "component", Value: name})} } ``` -------------------------------- ### Configure Event-Driven TCP Client with Defaults Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Demonstrates how to create a default configuration for the TCP client and override specific settings. This includes setting the target address, enabling auto-reconnect, and defining various timeouts and buffer sizes. ```go import ( "github.com/cyberinferno/go-utils/eventdriventcpclient" "time" ) cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:8080") // Override as needed cfg.AutoReconnect = true cfg.ReconnectInterval = 3 * time.Second cfg.ReadBufferSize = 8192 cfg.WriteTimeout = 5 * time.Second cfg.ReadTimeout = 30 * time.Second cfg.ConnectionTimeout = 10 * time.Second cfg.DataLengthBasedRead = true cfg.KeepAlive = true cfg.KeepAlivePeriod = 30 * time.Second // or set to 0 to use OS default when KeepAlive is true ``` -------------------------------- ### Cacher Interface Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md The Cacher interface defines the contract for cache operations, including getting or fetching data, deleting items, clearing the cache, and counting items. ```APIDOC ## Cacher Interface ### Description The `Cacher` interface defines a generic caching interface that works with any type `T`. It provides methods for retrieving and caching values, as well as managing the cache contents. ### Methods - **GetOrFetch(ctx context.Context, key string, ttl time.Duration, fetchFn FetchFunc[T]) (T, error)**: Retrieves a value from the cache. If the key is not found, it calls the `fetchFn` to fetch the value, caches it, and then returns it. - **Delete(key string)**: Removes a key from the cache. - **Clear()**: Removes all items from the cache. - **ItemCount() int**: Returns the number of items currently in the cache. - **DeleteByPrefix(prefix string) int**: Deletes all keys that start with the given prefix. Returns the number of keys deleted. ``` -------------------------------- ### Compare Algorithm Performance in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/perf-monitor.md Provides a pattern for benchmarking two different algorithms against the same dataset. It uses the Reset method to reuse the monitor and calculates the speedup ratio between implementations. ```go func compareAlgorithms(data []int) { pm := perfmonitor.NewPerformanceMonitor() pm.Start() resultA := algorithmA(data) pm.Stop() elapsedA := pm.ElapsedMilliseconds() pm.Reset() pm.Start() resultB := algorithmB(data) pm.Stop() elapsedB := pm.ElapsedMilliseconds() fmt.Printf("Algorithm A: %.2f ms\n", elapsedA) fmt.Printf("Algorithm B: %.2f ms\n", elapsedB) fmt.Printf("Speedup: %.2fx\n", elapsedA/elapsedB) if !resultsEqual(resultA, resultB) { log.Fatal("Algorithms produced different results!") } } ``` -------------------------------- ### Concurrent Deduplication with SafeSet Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safeset.md An example of using SafeSet for concurrent deduplication of integer IDs. Multiple goroutines add IDs to the set, and the set automatically handles uniqueness. ```go package main import ( "sync" "github.com/cyberinferno/go-utils/safeset" ) func main() { ids := safeset.NewSafeSet[int64]() var wg sync.WaitGroup for _, id := range []int64{1, 2, 1, 3, 2, 4, 1} { wg.Add(1) go func(v int64) { defer wg.Done() ids.Add(v) }(id) } wg.Wait() // ids.Size() is 4 (unique: 1, 2, 3, 4) } ``` -------------------------------- ### Structured Logging with Zerolog in Go Source: https://context7.com/cyberinferno/go-utils/llms.txt Implements structured logging using the zerolog library. Supports multiple log levels, contextual fields, and optional daily file rotation. Requires zerolog and the go-utils logger package. ```go package main import ( "os" "github.com/cyberinferno/go-utils/logger" "github.com/rs/zerolog" ) func main() { // Create console-only logger consoleLogger := logger.NewZerologLogger( zerolog.New(os.Stdout), "my-service", zerolog.InfoLevel, ) defer consoleLogger.Close() // Basic logging with structured fields consoleLogger.Info("Server started", logger.Field{Key: "port", Value: 8080}, logger.Field{Key: "env", Value: "production"}, ) // Output: {"level":"info","service":"my-service","port":8080,"env":"production","time":"...","message":"Server started"} consoleLogger.Error("Database connection failed", logger.Field{Key: "host", Value: "localhost"}, logger.Field{Key: "error", Value: "connection refused"}, ) // Create child logger with additional context requestLogger := consoleLogger.With( logger.Field{Key: "request_id", Value: "abc-123"}, logger.Field{Key: "user_id", Value: 42}, ) requestLogger.Debug("Processing request") // Create file logger with daily rotation fileLogger := logger.NewZerologFileLogger("my-service", "/var/log/myapp", zerolog.InfoLevel) defer fileLogger.Close() // Creates files like: /var/log/myapp/my-service_2024-01-15.log fileLogger.Warn("High memory usage", logger.Field{Key: "memory_mb", Value: 512}) } ``` -------------------------------- ### Creating a New Event-Driven TCP Client Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Instantiate a new event-driven TCP client with the provided configuration. ```APIDOC ## NewEventDrivenTCPClient Creates a new event-driven TCP client. The client starts in `Disconnected` state; call `Connect` to establish a connection. Call `Close` when done to release resources. ### Usage ```go cfg := eventdriventcpclient.DefaultEventDrivenTCPClientConfig("localhost:9000") client := eventdriventcpclient.NewEventDrivenTCPClient(cfg) default client.Close() ``` **Parameters:** - **config**: Connection and behavior settings (e.g. from `DefaultEventDrivenTCPClientConfig`). **Returns:** - A new `*EventDrivenTCPClient` ready to use. ``` -------------------------------- ### Unique Collection with SafeSet Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safeset.md Example of using SafeSet to collect unique string elements from a slice. It demonstrates adding elements and then iterating through the unique elements using Range. ```go package main import ( "fmt" "github.com/cyberinferno/go-utils/safeset" ) func main() { seen := safeset.NewSafeSet[string]() for _, name := range []string{"alice", "bob", "alice", "carol", "bob"} { seen.Add(name) } fmt.Println("unique names:", seen.Size()) seen.Range(func(v string) bool { fmt.Println(v) return true }) } ``` -------------------------------- ### Get SafeMap Size Source: https://github.com/cyberinferno/go-utils/blob/master/docs/safemap.md Retrieves the total number of key-value pairs currently stored in the SafeMap. Note that this operation may be inefficient for very large maps as it iterates through all entries. ```go n := m.Len() ``` -------------------------------- ### Byte Buffer Management and Null-Terminated Reading Source: https://github.com/cyberinferno/go-utils/blob/master/docs/utils.md Shows how to create fixed-length byte buffers from strings and extract the original string content by reading until the first null byte. ```go package main import ( "fmt" "github.com/cyberinferno/go-utils/utils" ) func main() { // Write a null-terminated string into a 64-byte buffer buf := utils.MakeFixedLengthStringBytes("hello", 64) // Read back the string (stops at null) s := utils.ReadStringFromBytes(buf) fmt.Println(s) // "hello" } ``` -------------------------------- ### Get Random Element from Slice (Go) Source: https://github.com/cyberinferno/go-utils/blob/master/docs/utils.md Retrieves a random element from a non-empty slice using generics. Panics if the slice is empty. For deterministic results in tests, seed the math/rand package. ```go import "github.com/cyberinferno/go-utils/utils" // With a slice of strings options := []string{"rock", "paper", "scissors"} choice := utils.GetRandomElement(options) // one of "rock", "paper", "scissors" // With a slice of integers ids := []int{101, 102, 103} id := utils.GetRandomElement(ids) // With a single-element slice (always returns that element) only := utils.GetRandomElement([]int{42}) // 42 ``` -------------------------------- ### Thread-Safe ID Generation in Go Source: https://context7.com/cyberinferno/go-utils/llms.txt Provides a thread-safe generator for monotonically increasing uint32 IDs. The generator can be initialized with a starting value. Requires the go-utils idgenerator package. ```go package main import ( "fmt" "sync" "github.com/cyberinferno/go-utils/idgenerator" ) func main() { // Create generator starting from 0 (first ID will be 1) gen := idgenerator.NewIdGenerator(0) // Generate sequential IDs fmt.Println(gen.Id()) // Output: 1 fmt.Println(gen.Id()) // Output: 2 fmt.Println(gen.Id()) // Output: 3 // Safe for concurrent use var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() id := gen.Id() fmt.Printf("Generated ID: %d\n", id) }() } wg.Wait() // Start from custom value customGen := idgenerator.NewIdGenerator(1000) fmt.Println(customGen.Id()) // Output: 1001 } ``` -------------------------------- ### Troubleshoot Redis Connection and Key Format in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md This Go code snippet demonstrates how to test the Redis connection using a Ping command and how to ensure consistent key formatting for cache operations. It helps diagnose issues related to Redis accessibility and key mismatches. ```go import ( "context" "fmt" "log" "github.com/go-redis/redis/v8" ) var ctx = context.Background() var redisClient *redis.Client // Assume redisClient is initialized elsewhere // Test Redis connection if err := redisClient.Ping(ctx).Err(); err != nil { log.Fatalf("Redis connection failed: %v", err) } // Check key format consistency userID := 123 // Example user ID key := fmt.Sprintf("user:%d", userID) // Ensure consistent format ``` -------------------------------- ### Sending Data via TCP Client Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Shows how to safely send data using the client, including a check for connection status to prevent unnecessary errors. ```go if client.IsConnected() { payload := []byte("hello world") err := client.Send(payload) if err != nil { log.Printf("Failed to send: %v", err) } } ``` -------------------------------- ### Log Messages with Structured Fields Source: https://github.com/cyberinferno/go-utils/blob/master/docs/logger.md Demonstrates how to log messages at various levels while attaching contextual key-value pairs using the Field struct. ```go log.Debug("cache hit", logger.Field{Key: "key", Value: "user:123"}) log.Info("request completed", logger.Field{Key: "status", Value: 200}, logger.Field{Key: "ms", Value: 42}) log.Warn("retry attempt", logger.Field{Key: "attempt", Value: 3}) log.Error("database connection failed", logger.Field{Key: "error", Value: err.Error()}) ``` -------------------------------- ### Error Handling: Fetch Function Errors (Go) Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Demonstrates how errors returned by the fetch function are propagated by the cacher. This example shows a scenario where the fetch function returns a 'user not found' error, which is then received by the caller. ```go fetchFn := func(ctx context.Context) (User, error) { return User{}, errors.New("user not found") } user, err := cacher.GetOrFetch(ctx, "user:1", ttl, fetchFn) if err != nil { // err will be "user not found" } ``` -------------------------------- ### User Service Caching with Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/cacher.md Demonstrates how to cache user data using the go-utils cacher with Redis. It simulates fetching user data from a database and utilizes a cache to store and retrieve it, reducing database load on subsequent requests. Dependencies include 'context', 'fmt', 'log', 'time', 'github.com/cyberinferno/go-utils/cacher', and 'github.com/redis/go-redis/v9'. ```go package main import ( "context" "fmt" "log" "time" "github.com/cyberinferno/go-utils/cacher" "github.com/redis/go-redis/v9" ) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` } type UserService struct { cacher cacher.Cacher[User] ctx context.Context } func NewUserService(redisClient *redis.Client) *UserService { return &UserService{ cacher: cacher.NewRedisCacher[User](redisClient), ctx: context.Background(), } } func (s *UserService) GetUser(userID int) (User, error) { key := fmt.Sprintf("user:%d", userID) fetchUser := func(ctx context.Context) (User, error) { // Simulate database query // In real implementation, query your database here return User{ ID: userID, Name: "John Doe", Email: "john@example.com", }, nil } return s.cacher.GetOrFetch(s.ctx, key, time.Hour, fetchUser) } func main() { redisClient := redis.NewClient(&redis.Options{ Addr: "localhost:6379", }) service := NewUserService(redisClient) // First call - cache miss, fetches from database user1, err := service.GetUser(1) if err != nil { log.Fatalf("Failed to get user: %v", err) } fmt.Printf("User 1: %+v\n", user1) // Second call - cache hit, returns immediately user2, err := service.GetUser(1) if err != nil { log.Fatalf("Failed to get user: %v", err) } fmt.Printf("User 2: %+v\n", user2) } ``` -------------------------------- ### Get TCP Client State in Go Source: https://github.com/cyberinferno/go-utils/blob/master/docs/eventdriventcpclient.md Retrieves the current connection state of the TCP client. The 'IsConnected' method provides a boolean indicating if the client is currently connected and ready for operations like sending data. ```go state := client.GetState() // ConnectionState if client.IsConnected() { // ready to Send } ```