blob: d298b52a6b79cf2f2367a3102c18a0c6f17a1979 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package main
import (
"context"
"net/http"
"sync"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
gerritpb "go.chromium.org/luci/common/proto/gerrit"
"go.fuchsia.dev/infra/gerrit"
)
// gerritClientKey is the key by which gerrit.Client structs are hashed in the
// gerritMultiClient cache.
type gerritClientKey struct {
hostname string
project string
}
// gerritMultiClient implements a wrapper around multiple per-project gerrit
// clients, as the gerrit.Client struct is scoped to a single repository.
type gerritMultiClient struct {
authClient *http.Client
clients map[gerritClientKey]*gerrit.Client
// Protects access to the `clients` map.
mu sync.Mutex
}
func (c *gerritMultiClient) getChange(
ctx context.Context,
change *buildbucketpb.GerritChange,
opts ...gerritpb.QueryOption,
) (*gerritpb.ChangeInfo, error) {
client, err := c.clientForProject(change.Host, change.Project)
if err != nil {
return nil, err
}
return client.GetChange(ctx, change.Change, opts...)
}
func (c *gerritMultiClient) clientForProject(hostname, project string) (*gerrit.Client, error) {
key := gerritClientKey{hostname: hostname, project: project}
c.mu.Lock()
defer c.mu.Unlock()
if client, ok := c.clients[key]; ok {
return client, nil
}
client, err := gerrit.NewClient(hostname, project, c.authClient)
if err != nil {
return nil, err
}
c.clients[key] = client
return client, nil
}