This commit is contained in:
19
routine/LICENSE
Normal file
19
routine/LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
MIT License Copyright (c) 2020 4devs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
3
routine/go.mod
Normal file
3
routine/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module gitoa.ru/go-4devs/closer/routine
|
||||
|
||||
go 1.16
|
||||
55
routine/runner.go
Normal file
55
routine/runner.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package routine
|
||||
|
||||
import "sync"
|
||||
|
||||
// nolint: gochecknoglobals
|
||||
var global = &WaitGroup{}
|
||||
|
||||
// Go run routine and add wait group.
|
||||
func Go(fnc func()) {
|
||||
global.Go(fnc)
|
||||
}
|
||||
|
||||
// Run run routines and add wait group.
|
||||
func Run(fnc ...func()) {
|
||||
global.Run(fnc...)
|
||||
}
|
||||
|
||||
// Close global routines.
|
||||
func Close() error {
|
||||
return global.Close()
|
||||
}
|
||||
|
||||
// Wait wait all go routines.
|
||||
func Wait() {
|
||||
global.Wait()
|
||||
}
|
||||
|
||||
// WaitGroup run func and wait when done.
|
||||
type WaitGroup struct {
|
||||
sync.WaitGroup
|
||||
}
|
||||
|
||||
// Close wait all routines and implement Closer.
|
||||
func (wg *WaitGroup) Close() error {
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Go add wait group to routines.
|
||||
func (wg *WaitGroup) Go(fnc func()) {
|
||||
wg.Run(fnc)
|
||||
}
|
||||
|
||||
// Run functions in routine and add wait group.
|
||||
func (wg *WaitGroup) Run(fnc ...func()) {
|
||||
wg.Add(len(fnc))
|
||||
|
||||
for i := range fnc {
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
fnc[i]()
|
||||
}(i)
|
||||
}
|
||||
}
|
||||
31
routine/runner_examplte_test.go
Normal file
31
routine/runner_examplte_test.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package routine_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/closer/routine"
|
||||
)
|
||||
|
||||
func ExampleGo() {
|
||||
defer routine.Close()
|
||||
routine.Go(func() {
|
||||
time.Sleep(time.Microsecond)
|
||||
fmt.Print("do some job")
|
||||
})
|
||||
|
||||
// Output: do some job
|
||||
}
|
||||
|
||||
func ExampleRun() {
|
||||
defer routine.Close()
|
||||
|
||||
routine.Run(func() {
|
||||
time.Sleep(time.Microsecond)
|
||||
fmt.Print("do some job. ")
|
||||
}, func() {
|
||||
fmt.Print("fast job in goroutine. ")
|
||||
})
|
||||
|
||||
// Output: fast job in goroutine. do some job.
|
||||
}
|
||||
69
routine/runner_test.go
Normal file
69
routine/runner_test.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package routine_test
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitoa.ru/go-4devs/closer/routine"
|
||||
)
|
||||
|
||||
func equal(t *testing.T, exp, res int) {
|
||||
t.Helper()
|
||||
|
||||
if exp != res {
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dt := make(map[string]int)
|
||||
|
||||
var mu sync.Mutex
|
||||
|
||||
fnc := func(name string) func() {
|
||||
return func() {
|
||||
time.Sleep(time.Millisecond)
|
||||
mu.Lock()
|
||||
dt[name]++
|
||||
mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
equal(t, 0, dt["once"])
|
||||
|
||||
routine.Go(fnc("once"))
|
||||
routine.Run(fnc("twice"), fnc("twice"))
|
||||
routine.Wait()
|
||||
|
||||
equal(t, 1, dt["once"])
|
||||
equal(t, 2, dt["twice"])
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dt := make(map[string]int)
|
||||
|
||||
var mu sync.Mutex
|
||||
|
||||
fnc := func(name string) func() {
|
||||
return func() {
|
||||
time.Sleep(time.Millisecond)
|
||||
mu.Lock()
|
||||
dt[name]++
|
||||
mu.Unlock()
|
||||
}
|
||||
}
|
||||
routine.Go(fnc("once"))
|
||||
routine.Run(fnc("twice"), fnc("twice"))
|
||||
|
||||
if err := routine.Close(); err != nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
equal(t, 1, dt["once"])
|
||||
equal(t, 2, dt["twice"])
|
||||
}
|
||||
Reference in New Issue
Block a user