go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/cmd/autogardener/gerrit.go (about) 1 // Copyright 2022 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package main 6 7 import ( 8 "context" 9 "net/http" 10 "sync" 11 12 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 13 gerritpb "go.chromium.org/luci/common/proto/gerrit" 14 15 "go.fuchsia.dev/infra/gerrit" 16 ) 17 18 // gerritClientKey is the key by which gerrit.Client structs are hashed in the 19 // gerritMultiClient cache. 20 type gerritClientKey struct { 21 hostname string 22 project string 23 } 24 25 // gerritMultiClient implements a wrapper around multiple per-project gerrit 26 // clients, as the gerrit.Client struct is scoped to a single repository. 27 type gerritMultiClient struct { 28 authClient *http.Client 29 clients map[gerritClientKey]*gerrit.Client 30 // Protects access to the `clients` map. 31 mu sync.Mutex 32 } 33 34 func (c *gerritMultiClient) getChange( 35 ctx context.Context, 36 change *buildbucketpb.GerritChange, 37 opts ...gerritpb.QueryOption, 38 ) (*gerritpb.ChangeInfo, error) { 39 client, err := c.clientForProject(change.Host, change.Project) 40 if err != nil { 41 return nil, err 42 } 43 return client.GetChange(ctx, change.Change, opts...) 44 } 45 46 func (c *gerritMultiClient) clientForProject(hostname, project string) (*gerrit.Client, error) { 47 key := gerritClientKey{hostname: hostname, project: project} 48 c.mu.Lock() 49 defer c.mu.Unlock() 50 if client, ok := c.clients[key]; ok { 51 return client, nil 52 } 53 client, err := gerrit.NewClient(hostname, project, c.authClient) 54 if err != nil { 55 return nil, err 56 } 57 c.clients[key] = client 58 return client, nil 59 }