From 9e46694ad4aedcbcf21a92f474ffa102450db86d Mon Sep 17 00:00:00 2001 From: Garet Halliday <ghalliday@gfxlabs.io> Date: Wed, 14 Sep 2022 15:14:20 -0500 Subject: [PATCH] only create workers when we need them --- lib/gat/gatling/pool/conn_pool/conn_pool.go | 34 +++++++++++++-------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/lib/gat/gatling/pool/conn_pool/conn_pool.go b/lib/gat/gatling/pool/conn_pool/conn_pool.go index af35f4e9..0347019d 100644 --- a/lib/gat/gatling/pool/conn_pool/conn_pool.go +++ b/lib/gat/gatling/pool/conn_pool/conn_pool.go @@ -18,6 +18,7 @@ type ConnectionPool struct { pool gat.Pool shards []*config.Shard + workers []*worker // see: https://github.com/golang/go/blob/master/src/runtime/chan.go#L33 // channels are a thread safe ring buffer implemented via a linked list of goroutines. // the idea is that goroutines are cheap, and we can afford to have one per pending request. @@ -34,18 +35,25 @@ func NewConnectionPool(pool gat.Pool, conf *config.Pool, user *config.User) *Con workerPool: make(chan *worker, 1+runtime.NumCPU()*4), } p.EnsureConfig(conf) - for i := 0; i < user.PoolSize; i++ { - p.addWorker() - } return p } -func (c *ConnectionPool) addWorker() { +func (c *ConnectionPool) getWorker() *worker { select { - case c.workerPool <- &worker{ - w: c, - }: + case w := <-c.workerPool: + return w default: + c.mu.Lock() + defer c.mu.Unlock() + if len(c.workers) < c.user.PoolSize { + next := &worker{ + w: c, + } + c.workers = append(c.workers, next) + return next + } else { + return <-c.workerPool + } } } @@ -71,7 +79,7 @@ func (c *ConnectionPool) GetUser() *config.User { } func (c *ConnectionPool) GetServerInfo() []*protocol.ParameterStatus { - return (<-c.workerPool).GetServerInfo() + return c.getWorker().GetServerInfo() } func (c *ConnectionPool) Shards() []gat.Shard { @@ -80,23 +88,23 @@ func (c *ConnectionPool) Shards() []gat.Shard { } func (c *ConnectionPool) Describe(ctx context.Context, client gat.Client, d *protocol.Describe) error { - return (<-c.workerPool).HandleDescribe(ctx, client, d) + return c.getWorker().HandleDescribe(ctx, client, d) } func (c *ConnectionPool) Execute(ctx context.Context, client gat.Client, e *protocol.Execute) error { - return (<-c.workerPool).HandleExecute(ctx, client, e) + return c.getWorker().HandleExecute(ctx, client, e) } func (c *ConnectionPool) SimpleQuery(ctx context.Context, client gat.Client, q string) error { - return (<-c.workerPool).HandleSimpleQuery(ctx, client, q) + return c.getWorker().HandleSimpleQuery(ctx, client, q) } func (c *ConnectionPool) Transaction(ctx context.Context, client gat.Client, q string) error { - return (<-c.workerPool).HandleTransaction(ctx, client, q) + return c.getWorker().HandleTransaction(ctx, client, q) } func (c *ConnectionPool) CallFunction(ctx context.Context, client gat.Client, f *protocol.FunctionCall) error { - return (<-c.workerPool).HandleFunction(ctx, client, f) + return c.getWorker().HandleFunction(ctx, client, f) } var _ gat.ConnectionPool = (*ConnectionPool)(nil) -- GitLab