How CasaOS Implements the Singleflight Pattern to Prevent Duplicate Requests
CasaOS prevents duplicate concurrent requests by shipping a custom generic singleflight package that deduplicates identical in-flight operations using a mutex-protected map and sync.WaitGroup, ensuring expensive functions execute exactly once regardless of how many goroutines request them.
CasaOS implements request deduplication through its own singleflight package located at pkg/singleflight/singleflight.go, a generic Go solution that suppresses redundant executions while multiple goroutines wait for a single result. This implementation leverages Go 1.18+ generics to support any result type T, eliminating thundering herd problems in device discovery and metadata caching subsystems.
Singleflight Pattern Architecture
The singleflight implementation centers on the Group[T] type, a generic container that tracks in-flight function calls and ensures only one execution occurs per unique key.
The Group Type
The Group[T] struct maintains thread-safe state using a mutex-protected map:
type Group[T any] struct {
mu sync.Mutex // protects the map of in‑flight calls
m map[string]*call[T] // key → call state
}
The map stores *call[T] pointers keyed by string identifiers, where each call represents an active or completed operation. When goroutines invoke Do or DoChan with the same key, the group coordinates execution through this centralized state.
Duplicate Detection and Execution Logic
When Do receives a request, it follows a strict coordination protocol:
- Duplicate detection – If
g.m[key]exists, the caller incrementsc.dups, releases the mutex, and blocks onc.wg.Wait(). - Single execution – If the key is new, the group creates a fresh
call[T], increments the wait-group, and executes the functionfnexactly once viag.doCall.
The call[T] struct stores the result values (val, err), a duplicate counter, and channels awaiting results. After doCall completes the original function, a deferred cleanup routine marks the call done with c.wg.Done(), removes the map entry (unless Forget was invoked), and broadcasts results to all waiting channels.
Implementing Request Deduplication in CasaOS
CasaOS utilizes the singleflight pattern anywhere expensive operations might coincide, such as network queries or filesystem scans. The generic API allows any subsystem to instantiate a typed Group for its specific data requirements.
Synchronous Deduplication with Do
For blocking operations like device metadata retrieval, CasaOS uses Group.Do to ensure only one backend request occurs:
import "github.com/IceWhaleTech/CasaOS/pkg/singleflight"
var deviceInfoSF singleflight.Group[*DeviceInfo]
func GetDeviceInfo(deviceID string) (*DeviceInfo, error) {
v, err, _ := deviceInfoSF.Do(deviceID, func() (*DeviceInfo, error) {
return fetchDeviceInfoFromBackend(deviceID)
})
return v, err
}
If multiple goroutines call GetDeviceInfo("123") simultaneously, only the first executes fetchDeviceInfoFromBackend. All others block on the internal WaitGroup and receive the same *DeviceInfo result without triggering additional network requests.
Asynchronous Operations with DoChan
For non-blocking scenarios like filesystem scanning, DoChan returns a channel that receives the result once execution completes:
var scanSF singleflight.Group[*ScanResult]
func ScanDirectory(path string) <-chan singleflight.Result[*ScanResult] {
return scanSF.DoChan(path, func() (*ScanResult, error) {
return runDeepScan(path)
})
}
The returned channel receives a Result[*ScanResult] containing the scanned data, any error, and a Shared flag. This flag indicates whether multiple callers shared the result, helping callers determine if deduplication occurred.
Real-World Usage of the Singleflight Pattern
CasaOS applies the singleflight pattern in several subsystems to prevent redundant work:
pkg/device/discovery.go– Usessingleflight.Groupto coalesce concurrent device-metadata fetches, preventing duplicate discovery packets.pkg/cache/metadata.go– Applies the pattern when reading metadata from external services, ensuring only one request hits the backend per resource.pkg/scan/scan.go– Demonstrates theDoChanAPI for deduplicated filesystem scans when multiple requests target the same directory.
Summary
- CasaOS ships a custom singleflight package at
pkg/singleflight/singleflight.gousing Go 1.18+ generics for type-safe deduplication. - The
Group[T]type coordinates execution through a mutex-protected map andsync.WaitGroup, blocking duplicate callers while a single goroutine executes the function. Doprovides synchronous deduplication suitable for database or network queries, whileDoChanenables asynchronous result retrieval for long-running operations.- The pattern prevents thundering herd issues in subsystems like device discovery and metadata caching by ensuring expensive operations execute exactly once per unique key.
Frequently Asked Questions
What is the singleflight pattern?
The singleflight pattern is a concurrency mechanism that prevents multiple goroutines from executing the same expensive operation simultaneously. When several requests arrive for the same resource, only the first executes the function while others wait; upon completion, all waiting goroutines receive the same result, eliminating redundant computations and network calls.
Why did CasaOS implement its own singleflight instead of using the standard library?
CasaOS created a custom implementation to leverage Go 1.18+ generics, whereas the standard golang.org/x/sync/singleflight package uses interface{} return types requiring type assertions. The CasaOS version allows compile-time type safety with Group[T], letting developers specify exact result types like *DeviceInfo or *ScanResult rather than generic empty interfaces.
How does CasaOS handle concurrent requests for the same key?
When concurrent requests arrive with identical keys, the first caller acquires the mutex, creates a call[T] entry in the map, and executes the function. Subsequent callers find the existing entry, increment a duplicate counter, release the lock, and block on c.wg.Wait(). After the original completes, deferred logic signals the wait-group and broadcasts the result to all waiting goroutines.
Where can I find examples of singleflight usage in CasaOS?
Production examples appear in pkg/device/discovery.go for device metadata deduplication, pkg/cache/metadata.go for external service request coalescing, and pkg/scan/scan.go for filesystem scan deduplication. Each file instantiates a singleflight.Group with a specific type parameter suited to its data requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →