github.com/wangyougui/gf/v2@v2.6.5/os/grpool/grpool.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/wangyougui/gf. 6 7 // Package grpool implements a goroutine reusable pool. 8 package grpool 9 10 import ( 11 "context" 12 "time" 13 14 "github.com/wangyougui/gf/v2/container/glist" 15 "github.com/wangyougui/gf/v2/container/gtype" 16 "github.com/wangyougui/gf/v2/os/gtimer" 17 "github.com/wangyougui/gf/v2/util/grand" 18 ) 19 20 // Func is the pool function which contains context parameter. 21 type Func func(ctx context.Context) 22 23 // RecoverFunc is the pool runtime panic recover function which contains context parameter. 24 type RecoverFunc func(ctx context.Context, exception error) 25 26 // Pool manages the goroutines using pool. 27 type Pool struct { 28 limit int // Max goroutine count limit. 29 count *gtype.Int // Current running goroutine count. 30 list *glist.List // List for asynchronous job adding purpose. 31 closed *gtype.Bool // Is pool closed or not. 32 } 33 34 // localPoolItem is the job item storing in job list. 35 type localPoolItem struct { 36 Ctx context.Context // Context. 37 Func Func // Job function. 38 } 39 40 const ( 41 minSupervisorTimerDuration = 500 * time.Millisecond 42 maxSupervisorTimerDuration = 1500 * time.Millisecond 43 ) 44 45 // Default goroutine pool. 46 var ( 47 defaultPool = New() 48 ) 49 50 // New creates and returns a new goroutine pool object. 51 // The parameter `limit` is used to limit the max goroutine count, 52 // which is not limited in default. 53 func New(limit ...int) *Pool { 54 var ( 55 pool = &Pool{ 56 limit: -1, 57 count: gtype.NewInt(), 58 list: glist.New(true), 59 closed: gtype.NewBool(), 60 } 61 timerDuration = grand.D( 62 minSupervisorTimerDuration, 63 maxSupervisorTimerDuration, 64 ) 65 ) 66 if len(limit) > 0 && limit[0] > 0 { 67 pool.limit = limit[0] 68 } 69 gtimer.Add(context.Background(), timerDuration, pool.supervisor) 70 return pool 71 } 72 73 // Add pushes a new job to the default goroutine pool. 74 // The job will be executed asynchronously. 75 func Add(ctx context.Context, f Func) error { 76 return defaultPool.Add(ctx, f) 77 } 78 79 // AddWithRecover pushes a new job to the default pool with specified recover function. 80 // 81 // The optional `recoverFunc` is called when any panic during executing of `userFunc`. 82 // If `recoverFunc` is not passed or given nil, it ignores the panic from `userFunc`. 83 // The job will be executed asynchronously. 84 func AddWithRecover(ctx context.Context, userFunc Func, recoverFunc RecoverFunc) error { 85 return defaultPool.AddWithRecover(ctx, userFunc, recoverFunc) 86 } 87 88 // Size returns current goroutine count of default goroutine pool. 89 func Size() int { 90 return defaultPool.Size() 91 } 92 93 // Jobs returns current job count of default goroutine pool. 94 func Jobs() int { 95 return defaultPool.Jobs() 96 }