package
0.9.8
Repository: https://github.com/lowl11/boost.git
Documentation: pkg.go.dev

# 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
}