// Licensed to the LF AI & Data foundation under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you 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 conc import ( "time" "github.com/panjf2000/ants/v2" "go.uber.org/zap" "github.com/milvus-io/milvus/pkg/log" ) type poolOption struct { // pre-allocs workers preAlloc bool // block or not when pool is full nonBlocking bool // duration to cleanup worker goroutine expiryDuration time.Duration // disable purge worker disablePurge bool // whether conceal panic when job has panic concealPanic bool // panicHandler when task panics panicHandler func(any) // preHandler function executed before actual method executed preHandler func() } func (opt *poolOption) antsOptions() []ants.Option { var result []ants.Option result = append(result, ants.WithPreAlloc(opt.preAlloc)) result = append(result, ants.WithNonblocking(opt.nonBlocking)) result = append(result, ants.WithDisablePurge(opt.disablePurge)) // ants recovers panic by default // however the error is not returned result = append(result, ants.WithPanicHandler(func(v any) { log.Error("Conc pool panicked", zap.Any("panic", v)) if !opt.concealPanic { panic(v) } })) if opt.panicHandler != nil { result = append(result, ants.WithPanicHandler(opt.panicHandler)) } if opt.expiryDuration > 0 { result = append(result, ants.WithExpiryDuration(opt.expiryDuration)) } return result } // PoolOption options function to setup pool. type PoolOption func(opt *poolOption) func defaultPoolOption() *poolOption { return &poolOption{ preAlloc: false, nonBlocking: false, expiryDuration: 0, disablePurge: false, concealPanic: false, } } func WithPreAlloc(v bool) PoolOption { return func(opt *poolOption) { opt.preAlloc = v } } func WithNonBlocking(v bool) PoolOption { return func(opt *poolOption) { opt.nonBlocking = v } } func WithDisablePurge(v bool) PoolOption { return func(opt *poolOption) { opt.disablePurge = v } } func WithExpiryDuration(d time.Duration) PoolOption { return func(opt *poolOption) { opt.expiryDuration = d } } func WithConcealPanic(v bool) PoolOption { return func(opt *poolOption) { opt.concealPanic = v } } func WithPreHandler(fn func()) PoolOption { return func(opt *poolOption) { opt.preHandler = fn } }