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  }