Documentation
¶
Overview ¶
Package etagcache provides an HTTP transport that makes conditional requests against the GitHub API.
GitHub returns an ETag with most GET responses and answers a repeat request carrying If-None-Match with 304 Not Modified when nothing changed. A 304 does not count against the rate limit. Transport remembers the ETag and body of each successful GET, sends the conditional headers on the next request for the same URL, and when GitHub answers 304, returns the cached response as if it were a fresh 200, so callers such as go-github never see the 304.
Use it as the base transport of an authenticated client:
cache := etagcache.NewTransport(nil)
client, err := clientv1.NewClientWithOptions(ctx, clientv1.ClientOptions{
Token: token,
Transport: cache,
})
// ... make requests, then:
fmt.Println(cache.Stats())
Entries are keyed by URL and by a hash of the Authorization header, so a store shared by clients with different tokens never serves one token's response to another. Cached bodies may contain private data; FileStore writes them with owner-only permissions.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Entry ¶
type Entry struct {
ETag string `json:"etag"`
LastModified string `json:"lastModified,omitempty"`
Header http.Header `json:"header"`
Body []byte `json:"body"`
}
Entry is a cached response.
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore keeps one JSON file per entry in a directory, so a cache survives between runs of a command-line tool. Files are written with owner-only permissions and replaced atomically. Entries are never evicted; remove the directory to clear the cache.
func NewFileStore ¶
NewFileStore returns a FileStore in dir, creating it if needed.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore keeps entries in memory, evicting the least recently used when MaxEntries is exceeded. It is safe for concurrent use.
func NewMemoryStore ¶
func NewMemoryStore(maxEntries int) *MemoryStore
NewMemoryStore returns a MemoryStore holding at most maxEntries entries; zero or negative means unlimited.
type Stats ¶
type Stats struct {
// Requests is the number of requests passed through the transport.
Requests int64
// Hits is the number of requests GitHub answered with 304 Not Modified;
// these did not count against the rate limit.
Hits int64
// Misses is the number of cacheable requests that were sent without a
// cached entry, or whose entry was stale.
Misses int64
// Uncacheable is the number of requests that bypassed the cache: methods
// other than GET and HEAD, or responses without an ETag.
Uncacheable int64
}
Stats counts what the transport did.
type Store ¶
type Store interface {
// Get returns the entry for key, or nil when there is none.
Get(key string) (*Entry, error)
// Set stores the entry for key, replacing any existing one.
Set(key string, entry *Entry) error
}
Store persists entries. Implementations must be safe for concurrent use.
type Transport ¶
type Transport struct {
// Next performs the requests. nil means http.DefaultTransport.
Next http.RoundTripper
// Store holds cached responses.
Store Store
// OnStoreError is called when the store fails to read or write; the
// request still proceeds without the cache. nil ignores store errors.
OnStoreError func(err error)
// contains filtered or unexported fields
}
Transport makes conditional requests using a Store. The zero value is not usable; use NewTransport.
func NewTransport ¶
func NewTransport(next http.RoundTripper) *Transport
NewTransport returns a Transport over next (nil means http.DefaultTransport) backed by a new MemoryStore.
func NewTransportWithStore ¶
func NewTransportWithStore(next http.RoundTripper, store Store) *Transport
NewTransportWithStore returns a Transport over next (nil means http.DefaultTransport) backed by store.