worker.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2021 ByteDance Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package gopool
  15. import (
  16. "fmt"
  17. //"github.com/flipped-aurora/gin-vue-admin/server/edge/util/logger"
  18. "github.com/sirupsen/logrus"
  19. "runtime/debug"
  20. "sync"
  21. "sync/atomic"
  22. )
  23. var workerPool sync.Pool
  24. func init() {
  25. workerPool.New = newWorker
  26. }
  27. type worker struct {
  28. pool *pool
  29. }
  30. func newWorker() interface{} {
  31. return &worker{}
  32. }
  33. func (w *worker) run() {
  34. go func() {
  35. for {
  36. var t *task
  37. w.pool.taskLock.Lock()
  38. if w.pool.taskHead != nil {
  39. t = w.pool.taskHead
  40. w.pool.taskHead = w.pool.taskHead.next
  41. atomic.AddInt32(&w.pool.taskCount, -1)
  42. }
  43. if t == nil {
  44. // if there's no task to do, exit
  45. w.close()
  46. w.pool.taskLock.Unlock()
  47. w.Recycle()
  48. return
  49. }
  50. w.pool.taskLock.Unlock()
  51. func() {
  52. defer func() {
  53. if r := recover(); r != nil {
  54. if w.pool.panicHandler != nil {
  55. w.pool.panicHandler(t.ctx, r)
  56. } else {
  57. msg := fmt.Sprintf("GOPOOL: panic in pool: %s: %v: %s", w.pool.name, r, debug.Stack())
  58. logrus.Error(t.ctx, msg)
  59. }
  60. }
  61. }()
  62. t.f()
  63. }()
  64. t.Recycle()
  65. }
  66. }()
  67. }
  68. func (w *worker) close() {
  69. w.pool.decWorkerCount()
  70. }
  71. func (w *worker) zero() {
  72. w.pool = nil
  73. }
  74. func (w *worker) Recycle() {
  75. w.zero()
  76. workerPool.Put(w)
  77. }