mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
add new function g.Go (#2943)
This commit is contained in:
45
util/gutil/gutil_goroutine.go
Normal file
45
util/gutil/gutil_goroutine.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
// Func is the function which contains context parameter.
|
||||
type Func func(ctx context.Context)
|
||||
|
||||
// RecoverFunc is the panic recover function which contains context parameter.
|
||||
type RecoverFunc func(ctx context.Context, exception error)
|
||||
|
||||
// Go creates a new asynchronous goroutine function with specified recover function.
|
||||
//
|
||||
// The parameter `recoverFunc` is called when any panic during executing of `goroutineFunc`.
|
||||
// If `recoverFunc` is given nil, it ignores the panic from `goroutineFunc` and no panic will
|
||||
// throw to parent goroutine.
|
||||
func Go(ctx context.Context, goroutineFunc Func, recoverFunc RecoverFunc) {
|
||||
if goroutineFunc == nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
defer func() {
|
||||
if exception := recover(); exception != nil {
|
||||
if recoverFunc != nil {
|
||||
if v, ok := exception.(error); ok && gerror.HasStack(v) {
|
||||
recoverFunc(ctx, v)
|
||||
} else {
|
||||
recoverFunc(ctx, gerror.NewCodef(gcode.CodeInternalPanic, "%+v", exception))
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
goroutineFunc(ctx)
|
||||
}()
|
||||
}
|
||||
64
util/gutil/gutil_z_unit_goroutine_test.go
Normal file
64
util/gutil/gutil_z_unit_goroutine_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package gutil_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
)
|
||||
|
||||
func Test_Go(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
wg = sync.WaitGroup{}
|
||||
array = garray.NewArray(true)
|
||||
)
|
||||
wg.Add(1)
|
||||
gutil.Go(ctx, func(ctx context.Context) {
|
||||
defer wg.Done()
|
||||
array.Append(1)
|
||||
}, nil)
|
||||
wg.Wait()
|
||||
t.Assert(array.Len(), 1)
|
||||
})
|
||||
// recover
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
wg = sync.WaitGroup{}
|
||||
array = garray.NewArray(true)
|
||||
)
|
||||
wg.Add(1)
|
||||
gutil.Go(ctx, func(ctx context.Context) {
|
||||
defer wg.Done()
|
||||
panic("error")
|
||||
array.Append(1)
|
||||
}, nil)
|
||||
wg.Wait()
|
||||
t.Assert(array.Len(), 0)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var (
|
||||
wg = sync.WaitGroup{}
|
||||
array = garray.NewArray(true)
|
||||
)
|
||||
wg.Add(1)
|
||||
gutil.Go(ctx, func(ctx context.Context) {
|
||||
panic("error")
|
||||
}, func(ctx context.Context, exception error) {
|
||||
defer wg.Done()
|
||||
array.Append(exception)
|
||||
})
|
||||
wg.Wait()
|
||||
t.Assert(array.Len(), 1)
|
||||
t.Assert(array.At(0), "error")
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user