...

Source file src/github.com/palantir/go-githubapp/githubapp/caching_client_creator.go

Documentation: github.com/palantir/go-githubapp/githubapp

     1  // Copyright 2018 Palantir Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package githubapp
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/google/go-github/v47/github"
    21  	lru "github.com/hashicorp/golang-lru"
    22  	"github.com/pkg/errors"
    23  	"github.com/shurcooL/githubv4"
    24  	"golang.org/x/oauth2"
    25  )
    26  
    27  const (
    28  	DefaultCachingClientCapacity = 64
    29  )
    30  
    31  // NewDefaultCachingClientCreator returns a ClientCreator using values from the
    32  // configuration or other defaults.
    33  func NewDefaultCachingClientCreator(c Config, opts ...ClientOption) (ClientCreator, error) {
    34  	delegate := NewClientCreator(
    35  		c.V3APIURL,
    36  		c.V4APIURL,
    37  		c.App.IntegrationID,
    38  		[]byte(c.App.PrivateKey),
    39  		opts...,
    40  	)
    41  	return NewCachingClientCreator(delegate, DefaultCachingClientCapacity)
    42  }
    43  
    44  // NewCachingClientCreator returns a ClientCreator that creates a GitHub client for installations of the app specified
    45  // by the provided arguments. It uses an LRU cache of the provided capacity to store clients created for installations
    46  // and returns cached clients when a cache hit exists.
    47  func NewCachingClientCreator(delegate ClientCreator, capacity int) (ClientCreator, error) {
    48  	cache, err := lru.New(capacity)
    49  	if err != nil {
    50  		return nil, errors.Wrapf(err, "failed to create cache")
    51  	}
    52  
    53  	return &cachingClientCreator{
    54  		cachedClients: cache,
    55  		delegate:      delegate,
    56  	}, nil
    57  }
    58  
    59  type cachingClientCreator struct {
    60  	cachedClients *lru.Cache
    61  	delegate      ClientCreator
    62  }
    63  
    64  func (c *cachingClientCreator) NewAppClient() (*github.Client, error) {
    65  	// app clients are not cached
    66  	return c.delegate.NewAppClient()
    67  }
    68  
    69  func (c *cachingClientCreator) NewAppV4Client() (*githubv4.Client, error) {
    70  	// app clients are not cached
    71  	return c.delegate.NewAppV4Client()
    72  }
    73  
    74  func (c *cachingClientCreator) NewInstallationClient(installationID int64) (*github.Client, error) {
    75  	// if client is in cache, return it
    76  	key := c.toCacheKey("v3", installationID)
    77  	val, ok := c.cachedClients.Get(key)
    78  	if ok {
    79  		if client, ok := val.(*github.Client); ok {
    80  			return client, nil
    81  		}
    82  	}
    83  
    84  	// otherwise, create and return
    85  	client, err := c.delegate.NewInstallationClient(installationID)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	c.cachedClients.Add(key, client)
    90  	return client, nil
    91  }
    92  
    93  func (c *cachingClientCreator) NewInstallationV4Client(installationID int64) (*githubv4.Client, error) {
    94  	// if client is in cache, return it
    95  	key := c.toCacheKey("v4", installationID)
    96  	val, ok := c.cachedClients.Get(key)
    97  	if ok {
    98  		if client, ok := val.(*githubv4.Client); ok {
    99  			return client, nil
   100  		}
   101  	}
   102  
   103  	// otherwise, create and return
   104  	client, err := c.delegate.NewInstallationV4Client(installationID)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	c.cachedClients.Add(key, client)
   109  	return client, nil
   110  }
   111  
   112  func (c *cachingClientCreator) NewTokenSourceClient(ts oauth2.TokenSource) (*github.Client, error) {
   113  	// token clients are not cached
   114  	return c.delegate.NewTokenSourceClient(ts)
   115  }
   116  
   117  func (c *cachingClientCreator) NewTokenClient(token string) (*github.Client, error) {
   118  	// token clients are not cached
   119  	return c.delegate.NewTokenClient(token)
   120  }
   121  
   122  func (c *cachingClientCreator) NewTokenV4Client(token string) (*githubv4.Client, error) {
   123  	// token clients are not cached
   124  	return c.delegate.NewTokenV4Client(token)
   125  }
   126  
   127  func (c *cachingClientCreator) NewTokenSourceV4Client(ts oauth2.TokenSource) (*githubv4.Client, error) {
   128  	// token clients are not cached
   129  	return c.delegate.NewTokenSourceV4Client(ts)
   130  }
   131  
   132  func (c *cachingClientCreator) toCacheKey(apiVersion string, installationID int64) string {
   133  	return fmt.Sprintf("%s:%d", apiVersion, installationID)
   134  }
   135  

View as plain text