blob: 3c945ddb031f08597c0d9b53f5ac2a2f3b3570fd [file] [edit]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package gitiles
import (
"context"
"golang.org/x/time/rate"
"google.golang.org/grpc"
gitilesProto "go.chromium.org/luci/common/proto/gitiles"
)
// NewThrottlingClient creates REST Gitiles client and consumes limiter quota
// on each API call to Gitiles. If there is no quota left, it blocks until
// there is.
func NewThrottlingClient(c Client, limiter *rate.Limiter) Client {
return &throttlingClient{
client: c,
limiter: limiter,
}
}
// throttlingClient is a wrapper around Gitiles client that throttles API calls.
type throttlingClient struct {
client Client
limiter *rate.Limiter
}
func (t *throttlingClient) Log(ctx context.Context, in *gitilesProto.LogRequest, opts ...grpc.CallOption) (*gitilesProto.LogResponse, error) {
if err := t.limiter.Wait(ctx); err != nil {
return nil, err
}
return t.client.Log(ctx, in, opts...)
}
func (t *throttlingClient) Refs(ctx context.Context, in *gitilesProto.RefsRequest, opts ...grpc.CallOption) (*gitilesProto.RefsResponse, error) {
if err := t.limiter.Wait(ctx); err != nil {
return nil, err
}
return t.client.Refs(ctx, in, opts...)
}
func (t *throttlingClient) Archive(ctx context.Context, in *gitilesProto.ArchiveRequest, opts ...grpc.CallOption) (*gitilesProto.ArchiveResponse, error) {
if err := t.limiter.Wait(ctx); err != nil {
return nil, err
}
return t.client.Archive(ctx, in, opts...)
}
func (t *throttlingClient) DownloadFile(ctx context.Context, in *gitilesProto.DownloadFileRequest, opts ...grpc.CallOption) (*gitilesProto.DownloadFileResponse, error) {
if err := t.limiter.Wait(ctx); err != nil {
return nil, err
}
return t.client.DownloadFile(ctx, in, opts...)
}
func (t *throttlingClient) Projects(ctx context.Context, in *gitilesProto.ProjectsRequest, opts ...grpc.CallOption) (*gitilesProto.ProjectsResponse, error) {
if err := t.limiter.Wait(ctx); err != nil {
return nil, err
}
return t.client.Projects(ctx, in, opts...)
}