package gojs import ( "github.com/ssgo/log" "github.com/ssgo/u" "runtime" "sync" ) type LB struct { args []any pool []*Runtime logger *log.Logger debug bool lock sync.RWMutex num int } type LBConfig struct { Num uint Args []any Debug bool } func (p *LB) Get() *Runtime { p.lock.RLock() i := u.GlobalRand1.Intn(p.num) rt := p.pool[i] p.lock.RUnlock() return rt } func NewLB(plg *Program, opt LBConfig, logger *log.Logger) *LB { if opt.Num == 0 { opt.Num = uint(runtime.NumCPU()) } if opt.Num > uint(runtime.NumCPU())*2 { opt.Num = uint(runtime.NumCPU()) * 2 } p := &LB{ pool: make([]*Runtime, opt.Num), args: opt.Args, logger: logger, debug: opt.Debug, num: int(opt.Num), } p.lock.Lock() for i := 0; i < int(opt.Num); i++ { rt := New() err := rt.StartFromProgram(plg) if err == nil { _, err = rt.RunMain(p.args...) } if err != nil { p.logger.Error(err.Error()) } p.pool[i] = rt } p.lock.Unlock() return p } func NewLBByFile(file string, opt LBConfig, logger *log.Logger) *LB { if plg, err := CompileFile(file); err == nil { return NewLB(plg, opt, logger) } else { return nil } } func NewLBByCode(code, refFile string, opt LBConfig, logger *log.Logger) *LB { if plg, err := CompileCode(code, refFile); err == nil { return NewLB(plg, opt, logger) } else { return nil } }