# README
async
Channel
Close channel without panic.
Sometimes closing channel throws panic
package main
import "github.com/lowl11/boost/pkg/io/async"
func main() {
someChan := make(chan int)
async.CloseChan(someChan)
async.CloseChan(someChan) // does not panic after second closing
}
Group
More simple way of using errgroup with semaphores
package main
import (
"fmt"
"github.com/lowl11/boost/pkg/io/async"
"log"
)
func main() {
gr := async.NewGroup(10) // 10 - max 10 goroutines at moment
// or another way to set max goroutines
gr = async.NewGroup().SetLimit(10)
// !!! Max goroutines is optional
gr.Run(func() error {
fmt.Println("first async action #1")
return nil
})
gr.Run(func() error {
fmt.Println("first async action #2")
return nil
})
if err := gr.Wait(); err != nil {
log.Fatal(err)
}
}
Map
There is sync.Map implementation of thead safe map.
But sometimes its more efficient to use map but with mutex
package main
import (
"fmt"
"github.com/lowl11/boost/pkg/io/async"
)
func main() {
// init
theadSafeMap := async.NewMap[string, string](10) // 10 - start size of map (optional)
// store
theadSafeMap.Store("key1", "value1")
// load
value1, ok := theadSafeMap.Load("key1")
if !ok {
fmt.Println("key1 does not exist")
}
fmt.Println("value1:", value1) // prints "value1"
// keys
theadSafeMap.Keys() // returns all keys as []string slice
// len
theadSafeMap.Len() // returns length of map as int
// delete
theadSafeMap.Delete("key1") // removes element from map by key
// each
// iterates for every element in map
theadSafeMap.Each(func(key string, value string) bool {
fmt.Printf("%s - %s\n", key, value)
return true // true - go, false - stop iterating
})
}
Semaphore
Of course, there is builtin semaphore implementation, but its complicated :D
package main
import (
"fmt"
"github.com/lowl11/boost/pkg/io/async"
)
func main() {
// init
semaphore := async.NewSemaphore(10) // 10 - max count of goroutines
defer semaphore.Close() // closes inner channel
// say "goroutine in use"
semaphore.Acquire()
// say "goroutine done"
semaphore.Release()
// example
for i := 0; i < 100000; i++ {
semaphore.Acquire()
go func(i int) {
semaphore.Release()
fmt.Println("#", i+1)
}(i)
}
}
Wait
Sometimes developers need to call couple actions at once (parallel)
package main
import (
"github.com/lowl11/boost/pkg/io/async"
"log"
)
func main() {
actions := []func() error{
do1, do2, do3,
}
if err := async.WaitAll(actions); err != nil {
log.Fatal(err)
}
// also, can run actions with limits (semaphore)
if err := async.WaitAll(actions, 10); err != nil {
log.Fatal(err)
}
}
func do1() error {
return nil
}
func do2() error {
return nil
}
func do3() error {
return nil
}