ghcache

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 3, 2023 License: Apache-2.0 Imports: 26 Imported by: 0

README

ghCache

What?

ghCache is an HTTP cache optimized for caching responses from the GitHub API (https://api.github.com). Specifically, it has the following non-standard caching behavior:

  • Every cache hit is revalidated with a conditional HTTP request to GitHub regardless of cache entry freshness (TTL). The 'Cache-Control' header is ignored and overwritten to achieve this.
  • Concurrent requests for the same resource are coalesced and share a single request/response from GitHub instead of each request resulting in a corresponding upstream request and response.

ghCache also provides prometheus instrumentation to expose cache activity, request duration, and API token usage/savings.

Why?

The most important behavior of ghCache is the mandatory cache entry revalidation. While this property would cause most API caches to use tokens excessively, in the case of GitHub, we can actually save API tokens. This is because conditional requests for unchanged resources don't cost any API tokens!!! See: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests Free revalidation allows us to ensure that every request is satisfied with the most up to date resource without actually spending an API token unless the resource has been updated since we last checked it.

Request coalescing is beneficial for use cases in which the same resource is requested multiple times in rapid succession. Normally these requests would each result in an upstream request to GitHub, potentially costing API tokens, but with request coalescing at most one token is used. This particularly helps when many handlers react to the same event like in Prow's hook component.

Documentation

Overview

Package ghcache implements an HTTP cache optimized for caching responses from the GitHub API (https://api.github.com).

Specifically, it enforces a cache policy that revalidates every cache hit with a conditional request to upstream regardless of cache entry freshness because conditional requests for unchanged resources don't cost any API tokens!!! See: https://developer.github.com/v3/#conditional-requests

It also provides request coalescing and prometheus instrumentation.

Index

Constants

View Source
const LogMessageWithDiskPartitionFields = "Not using a partitioned cache because legacyDisablePartitioningByAuthHeader is true"

Variables

This section is empty.

Functions

func CacheModeIsFree

func CacheModeIsFree(mode CacheResponseMode) bool

func NewDiskCache

func NewDiskCache(roundTripper http.RoundTripper, cacheDir string, cacheSizeGB, maxConcurrency int, legacyDisablePartitioningByAuthHeader bool, cachePruneInterval time.Duration, throttlingTimes RequestThrottlingTimes) http.RoundTripper

NewDiskCache creates a GitHub cache RoundTripper that is backed by a disk cache. It supports a partitioned cache.

func NewFromCache

func NewFromCache(roundTripper http.RoundTripper, cache CachePartitionCreator, maxConcurrency int, throttlingTimes RequestThrottlingTimes) http.RoundTripper

NewFromCache creates a GitHub cache RoundTripper that is backed by the specified httpcache.Cache implementation.

func NewMemCache

func NewMemCache(roundTripper http.RoundTripper, maxConcurrency int, throttlingTimes RequestThrottlingTimes) http.RoundTripper

NewMemCache creates a GitHub cache RoundTripper that is backed by a memory cache. It supports a partitioned cache.

func NewRedisCache

func NewRedisCache(roundTripper http.RoundTripper, redisAddress string, maxConcurrency int, throttlingTimes RequestThrottlingTimes) http.RoundTripper

NewRedisCache creates a GitHub cache RoundTripper that is backed by a Redis cache. Important note: The redis implementation does not support partitioning the cache which means that requests to the same path from different tokens will invalidate each other.

func Prune

func Prune(baseDir string, now func() time.Time)

Types

type CachePartitionCreator

type CachePartitionCreator func(partitionKey string, expiresAt *time.Time) httpcache.Cache

CachePartitionCreator creates a new cache partition using the given key

type CacheResponseMode

type CacheResponseMode string
const (
	CacheModeHeader = "X-Cache-Mode"

	ModeError   CacheResponseMode = "ERROR"    // internal error handling request
	ModeNoStore CacheResponseMode = "NO-STORE" // response not cacheable
	ModeMiss    CacheResponseMode = "MISS"     // not in cache, request proxied and response cached.
	ModeChanged CacheResponseMode = "CHANGED"  // cache value invalid: resource changed, cache updated
	ModeSkip    CacheResponseMode = "SKIP"     // cache was skipped, not applicable. e.g. POST request.
	// The modes below are the happy cases in which the request is fulfilled for
	// free (no API tokens used).
	ModeCoalesced   CacheResponseMode = "COALESCED"   // coalesced request, this is a copied response
	ModeRevalidated CacheResponseMode = "REVALIDATED" // cached value revalidated and returned

	// TokenBudgetIdentifierHeader is used to identify the token budget for
	// which metrics should be recorded if set. If unset, the sha256sum of
	// the Authorization header will be used.
	TokenBudgetIdentifierHeader = "X-PROW-GHCACHE-TOKEN-BUDGET-IDENTIFIER"

	// TokenExpiryAtHeader includes a date at which the passed token expires and all associated caches
	// can be cleaned up. It's value must be in RFC3339 format.
	TokenExpiryAtHeader = "X-PROW-TOKEN-EXPIRES-AT"
)

Cache response modes describe how ghcache fulfilled a request.

type RequestThrottlingTimes

type RequestThrottlingTimes struct {
	// contains filtered or unexported fields
}

RequestThrottlingTimes keeps the information about throttling times per API and request methods

func NewRequestThrottlingTimes

func NewRequestThrottlingTimes(requestThrottlingTime, requestThrottlingTimeV4, requestThrottlingTimeForGET, requestThrottlingMaxDelayTime, requestThrottlingMaxDelayTimeV4 uint) RequestThrottlingTimes

NewRequestThrottlingTimes creates a new RequestThrottlingTimes and returns it

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL