coalesce is a high-performance, type-safe request coalescing and cache stampede (thundering herd) protection library for Go (1.21+).
It elegantly collapses thousands of concurrent, redundant, or heavy operations (such as database queries, microservice calls, or resource initializations) into a single execution, while providing surgical-grade resource management through dynamic orphan task auto-cancellation.
- 🛡️ Thundering Herd Shield: Collapses mass concurrent flights into exactly one execution.
- ⚡ Type-Safe Generics: Built from the ground up utilizing Go 1.21+ generics for compile-time safety—no more
interface{}casting. - 🛑 Smart Auto-Cancellation (Orphan Teardown): If all waiting clients timeout or abort,
coalesceautomatically cuts off the background worker via context propagation, eliminating ghost tasks from draining your system resources. - 🔄 Resilient Failure Isolation: Failed background initializations are instantly evicted from tracking states, allowing immediate retries without polluting upper cache tiers.
- 🔀 Atomic Cache Handover: Built-in hooks natively synchronize results with your infrastructure storage (e.g., Redis, LRU) safely with zero-copy friction.
go get -u github.com/gophini/coalesce| Component | Architecture Role | Best Used For |
|---|---|---|
coalesce.Task[T] |
Single-resource lazy coordinator | Global singletons, heavy application configs, DB connection pool setups. |
coalesce.Group[K, V] |
Keyspaced dynamic synchronization center | Dynamic cache warming, HTTP/gRPC hot-key protection, dynamic metadata fetching. |
This is the standard industrial pattern to protect database infrastructures against sudden traffic surges or hot-key cache expiration.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/gophini/coalesce"
)
// Define your favorite local or distributed cache structure
type MemoryCache struct {
// e.g., sync.Map or LRU cache
}
func (m *MemoryCache) Get(key string) (any, bool) { return nil, false }
func (m *MemoryCache) Add(key string, value any) {}
func main() {
// Initialize the group barrier with an underlying context and optional cache tier
group := coalesce.NewGroup[string, string](
coalesce.WithGroupContext[string, string](context.Background()),
coalesce.WithGroupTaskAutoCancel[string, string](true),
coalesce.WithGroupCache[string, string](&MemoryCache{}), // your cache instance
)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
// Heavy database operation simulation
fetchDB := func(bgCtx context.Context) (string, error) {
time.Sleep(100 * time.Millisecond) // Simulate slow query
return "user_profile_data", nil
}
// 100 concurrent goroutines calling this simultaneously will trigger the DB exactly ONCE.
val, shared, err := group.Get(ctx, "user_id_101", fetchDB)
if err != nil {
log.Fatalf("failed to fetch: %v", err)
}
// shared = true for all concurrent waiters, false only for the definitive winner.
fmt.Printf("Data: %s, Shared: %t\n", val, shared)
}When you need a single object (e.g., an encrypted configuration manager) to be safely instantiated on-demand under severe startup traffic.
package main
import (
"context"
"fmt"
"time"
"github.com/gophini/coalesce"
)
func main() {
// Enable AutoCancel so if all client HTTP requests abort, the background setup halts instantly.
task := coalesce.NewTask[string](
coalesce.WithTaskAutoCancel[string](true),
)
setupResource := func(ctx context.Context) (string, error) {
time.Sleep(500 * time.Millisecond)
return "global_connection_established", nil
}
// Blocks gracefully and returns exactly when setup completes
res, shared, _ := task.Get(context.Background(), setupResource)
fmt.Printf("Resource: %s, Shared: %t\n", res, shared)
}coalesce leverages Go's native memory barriers (sync.RWMutex Double-Check locking and sync/atomic fences) to minimize CPU cache-line bouncing.
To test concurrency safety under heavy data-race analysis, run:
go test -v -race -count=5 ./...
Distributed under the MIT License. See LICENSE for more information.