Go Routines
Zero-value Mutexes are Valid
The zero-value of sync.Mutex
and sync.RWMutex
is valid, so you almost never need a pointer to a mutex.
If you use a struct by pointer, then the mutex should be a non-pointer field on it. Do not embed the mutex on the struct, even if the struct is not exported.
The Mutex
field, and the Lock
and Unlock
methods are unintentionally part of the exported API of SMap
The mutex and its methods are implementation details of SMap
hidden from its callers.
Defer to Clean Up
Use defer to clean up resources such as files and locks.
Channel Size is One or None
Channels should usually have a size of one or be unbuffered. By default, channels are unbuffered and have a size of zero. Any other size must be subject to a high level of scrutiny. Consider how the size is determined, what prevents the channel from filling up under load and blocking writers, and what happens when this occurs.
Don't fire-and-forget goroutines
Goroutines are lightweight, but they're not free: at minimum, they cost memory for their stack and CPU to be scheduled. While these costs are small for typical uses of goroutines, they can cause significant performance issues when spawned in large numbers without controlled lifetimes. Goroutines with unmanaged lifetimes can also cause other issues like preventing unused objects from being garbage collected and holding onto resources that are otherwise no longer used.
In general, every goroutine:
must have a predictable time at which it will stop running; or
there must be a way to signal to the goroutine that it should stop
Wait for goroutines to exit
Given a goroutine spawned by the system, there must be a way to wait for the goroutine to exit. There are two popular ways to do this:
Use a
sync.WaitGroup
. Do this if there are multiple goroutines that you want to wait for
Add another
chan struct{}
that the goroutine closes when it's done. Do this if there's only one goroutine.
Last updated