// Copyright 2021 ByteDance Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gopool import ( "fmt" //"github.com/flipped-aurora/gin-vue-admin/server/edge/util/logger" "github.com/sirupsen/logrus" "runtime/debug" "sync" "sync/atomic" ) var workerPool sync.Pool func init() { workerPool.New = newWorker } type worker struct { pool *pool } func newWorker() interface{} { return &worker{} } func (w *worker) run() { go func() { for { var t *task w.pool.taskLock.Lock() if w.pool.taskHead != nil { t = w.pool.taskHead w.pool.taskHead = w.pool.taskHead.next atomic.AddInt32(&w.pool.taskCount, -1) } if t == nil { // if there's no task to do, exit w.close() w.pool.taskLock.Unlock() w.Recycle() return } w.pool.taskLock.Unlock() func() { defer func() { if r := recover(); r != nil { if w.pool.panicHandler != nil { w.pool.panicHandler(t.ctx, r) } else { msg := fmt.Sprintf("GOPOOL: panic in pool: %s: %v: %s", w.pool.name, r, debug.Stack()) logrus.Error(t.ctx, msg) } } }() t.f() }() t.Recycle() } }() } func (w *worker) close() { w.pool.decWorkerCount() } func (w *worker) zero() { w.pool = nil } func (w *worker) Recycle() { w.zero() workerPool.Put(w) }