github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/goroutines_http.go (about) 1 package f 2 3 import ( 4 "fmt" 5 "github.com/panjf2000/ants/v2" 6 ) 7 8 // GoPoolWithFunc ants.PoolWithFunc. 9 type GoPoolWithFunc struct { 10 *ants.PoolWithFunc 11 } 12 13 // GoHttpHandle a Http Handle Goroutines Pool. 14 var GoHttpHandle *GoPoolWithFunc 15 16 func init() { 17 GoHttpHandle = NewHttpHandlePool(100000) 18 } 19 20 // GoHttpHandleRequest Handling input and output. 21 type GoHttpHandleRequest struct { 22 Body []byte // Input 23 Param interface{} // Input 24 HandleFunc func() // HandleFunc: SetResult(result) 25 _result chan interface{} // Output 26 } 27 28 // SetResult Write to a output channel. 29 func (g *GoHttpHandleRequest) SetResult(result interface{}) { 30 if g._result == nil { 31 g._result = make(chan interface{}, 1) 32 } 33 g._result <- result 34 } 35 36 // GetResult Read from a output channel. 37 func (g *GoHttpHandleRequest) GetResult() interface{} { 38 if g._result == nil { 39 return nil 40 } 41 return <-g._result 42 } 43 44 // Invoke Handling logic, return throttle limit error. 45 // Throttle the requests traffic with ants pool. This process is asynchronous and 46 // you can receive a result from the channel defined outside. 47 func (g *GoHttpHandleRequest) Invoke(pool *GoPoolWithFunc) error { 48 return pool.Invoke(g) 49 } 50 51 // NewHttpHandleRequest Create a http request handler. 52 func NewHttpHandleRequest(param interface{}) *GoHttpHandleRequest { 53 return &GoHttpHandleRequest{ 54 Body: nil, 55 Param: param, 56 HandleFunc: nil, 57 _result: make(chan interface{}, 1), 58 } 59 } 60 61 // NewHttpHandleRequestBody Create a http request handler. 62 func NewHttpHandleRequestBody(body []byte) *GoHttpHandleRequest { 63 return &GoHttpHandleRequest{ 64 Body: body, 65 Param: nil, 66 HandleFunc: nil, 67 _result: make(chan interface{}, 1), 68 } 69 } 70 71 // NewHttpHandlePool Create a Http Handle Goroutines Pool. 72 // @poolTotalSize 100000: SetHeader total goroutines and tasks. 73 func NewHttpHandlePool(poolTotalSize int, options ...ants.Options) *GoPoolWithFunc { 74 var option ants.Options 75 if len(options) > 0 { 76 option = options[0] 77 } else { 78 option = ants.Options{ 79 ExpiryDuration: ants.DefaultCleanIntervalTime, 80 PreAlloc: true, 81 Nonblocking: true, 82 MaxBlockingTasks: 0, 83 PanicHandler: func(err interface{}) { 84 _ = fmt.Errorf(" GoHttpHandle/worker: %s\n %v", Now().LocalTimeString(), err) 85 }, 86 } 87 } 88 89 poolWithFunc, _ := ants.NewPoolWithFunc(poolTotalSize, func(payload interface{}) { 90 request, ok := payload.(*GoHttpHandleRequest) 91 if !ok { 92 return 93 } 94 95 request.HandleFunc() 96 }, ants.WithOptions(option)) 97 return &GoPoolWithFunc{PoolWithFunc: poolWithFunc} 98 } 99 100 // NewHttpHandlePoolWithThrottle Create a Http Handle Goroutines Pool. 101 // @throttleLimitNumber 1000: More than it, return HTTP code 429 Too Many Requests. 102 // @poolTotalSize 100000: SetHeader total goroutines and tasks. 103 func NewHttpHandlePoolWithThrottle(throttleLimitNumber, poolTotalSize int, options ...ants.Options) *GoPoolWithFunc { 104 var option ants.Options 105 if len(options) > 0 { 106 option = options[0] 107 } else { 108 option = ants.Options{ 109 ExpiryDuration: ants.DefaultCleanIntervalTime, 110 PreAlloc: true, 111 Nonblocking: false, 112 MaxBlockingTasks: throttleLimitNumber, 113 PanicHandler: func(err interface{}) { 114 _ = fmt.Errorf(" GoHttpHandle/worker: %s\n %v", Now().LocalTimeString(), err) 115 }, 116 } 117 } 118 119 poolWithFunc, _ := ants.NewPoolWithFunc(poolTotalSize, func(payload interface{}) { 120 request, ok := payload.(*GoHttpHandleRequest) 121 if !ok { 122 return 123 } 124 125 request.HandleFunc() 126 }, ants.WithOptions(option)) 127 return &GoPoolWithFunc{PoolWithFunc: poolWithFunc} 128 }