π± rainbowcat
A useful library for Go.
π¨π³ δΈζηζ¬
Installation
go get github.com/rambollwong/rainbowcat
Requires Go 1.26+.
Packages
| Package |
Description |
cache |
Generic FIFO cache with optional thread-safety and eviction callback |
global |
Global sync.WaitGroup for graceful shutdown coordination |
logo |
ASCII art banner printer (cosmetic) |
pipeline |
Multi-stage parallel task pipeline β each stage runs concurrently |
pool |
Goroutine worker pool + []byte reuse pool |
signal |
OS signal handling (SIGINT/SIGTERM) with platform variants |
smtp |
SMTP email sender (wraps gomail) |
task |
Timer/ticker-based task monitor with pluggable DataStore |
time |
Single helper: UseLocalUTC() |
types |
Generic helpers: Set[T], Entry[K,V], Clonable[T] |
util |
Slice & map operations, bytes/hex, gzip, fibonacci, string parsing |
writer/filewriter |
Rolling file writers: size-based and time-based |
cache
A generic fixed-size FIFO cache backed by container/list + map, with optional sync.RWMutex thread-safety and eviction callback.
c := cache.NewFIFOCache[int, string](100, true)
c.Put(1, "hello")
v, ok := c.Get(1) // "hello", true
c.Size() // 1
global
Process-global sync.WaitGroup for tracking running goroutines during graceful shutdown.
global.RunTask(func() {
// do work
})
// ... wait for all tasks to finish
global.Wait()
pool
Worker pool β bounded goroutine pool with functional options:
wp := pool.NewWorkerPool(4,
pool.WithBufferSize(16),
pool.WithRejectHandler(func(t pool.Task) { /* log */ }),
)
err := wp.Submit(func() { /* do work */ })
wp.Close()
Bytes pool β sync.Pool wrapper for []byte reuse:
bp := pool.NewBytesPool(512, pool.DefaultMaxBytesCap)
bz := bp.Get()
defer bp.Put(bz)
pipeline
Multi-stage concurrent pipeline. Each stage has configurable concurrency; output of stage N becomes input of stage N+1.
stage1 := pipeline.GenericTaskProvider[int, string](func(i int) (string, bool) {
return fmt.Sprintf("got %d", i), true
})
pp, _ := pipeline.RunParallelTaskPipeline(2, []uint8{2, 1}, stage1)
pp.PushJob(42)
fmt.Println(<-pp.OutputC()) // "got 42"
pp.Close()
signal
Watch for SIGINT/SIGTERM and execute callbacks:
signal.WatchExitSignal(func() {
fmt.Println("shutting down...")
})
signal.WaitForKeyPress() // cross-platform "press any key"
task
Timer/ticker scheduling with a pluggable DataStore:
tm := &task.TasksMonitor{}
tm.SetDataStore(myDataStore)
tm.RegisterTickerForTasks(time.Minute, "cleanup", func(d task.Data) {
// periodic cleanup
})
tm.Start()
types
Thread-safe generic Set[T] backed by map + sync.RWMutex:
s := types.NewSet[int]()
s.Put(1) // true
s.Put(1) // false (already exists)
s.Exist(1) // true
s.Size() // 1
s.Range(func(v int) bool { fmt.Println(v); return true })
util
Rich collection of slice and map utilities (inspired by samber/lo), plus gzip compression, fibonacci, byte conversions, and string parsing:
// slice operations
util.SliceFilter([]int{1, 2, 3, 4}, func(i int, v int) bool { return v%2 == 0 })
util.SliceShuffle([]int{1, 2, 3, 4, 5})
util.SliceGroupBy([]string{"a", "ab", "abc"}, len) // map[1:["a"] 2:["ab"] 3:["abc"]
util.SliceCutChunks([]int{1, 2, 3, 4, 5}, 2) // [[1 2] [3 4] [5]]
// map operations
util.MapKeys(myMap) // []K
util.MapValues(myMap) // []V
util.MapInvert(myMap) // swap keys β values
util.MapAssign(m1, m2, m3) // merge left-to-right
// gzip
data, _ := util.GZipCompressBytes(raw)
raw, _ := util.GZipDecompressBytes(data)
writer/filewriter
Size-based rolling β rotates when file exceeds a size limit:
w, _ := filewriter.NewSizeRollingFileWriter("./logs", "app", 10, 64<<20)
w.Write([]byte("log line\n"))
w.Close()
Time-based rolling β rotates at time-period boundaries:
w, _ := filewriter.NewTimeRollingFileWriter("./logs", "app", 30, filewriter.RollingPeriodDay)
w.Write([]byte("log line\n"))
w.Close()
Conventions
- Go generics everywhere (1.26+) β
any over interface{}.
- Prefer standard library (
slices, maps, math/rand/v2) over hand-rolled equivalents.
- Functional options pattern (
pool.Option, cache thread-safety toggle).
- Exported symbols have doc comments. Pointer receivers for mutable structs.
- Tests colocated (
_test.go), using standard testing + github.com/stretchr/testify.
- Sentinel errors:
var ErrXxx = errors.New(...).
License
MIT