forwardcache

package module
v2.0.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2018 License: Apache-2.0 Imports: 8 Imported by: 0

README

forwardcache

Build Status Coverage Status GitHub license GoDoc

A distributed forward caching proxy for Go's http.Client using httpcache and heavily inspired by groupcache. Backed by a lot of existing cache backends thanks to httpcache. A per host LRU algorithm is provided to optionally front any existing cache. Like groupcache, forwardcache "is a client library as well as a server. It connects to its own peers."

In simple terms, it is a distributed cache for HEAD and GET requests. It follows the HTTP RFC so it will only cache cacheable responses (like browsers do).

Docs on godoc.org

+---------------------------------+
|                                 |
|         origin servers          |
|                                 |
+--+-------+-------+-----------+--+
   ^       ^       ^           ^
   |       |       |           |
   |       |       |           |
+-----+ +-----+ +-----+     +-----+
|cache| |cache| |cache|     |cache|
+--+--+ +--+--+ +--+--+     +--+--+
|     | |     | |     |     |     |
|  1  +-+  2  +-+  3  +--|--+  N  |
|     | |     | |     |     |     |
+-----+ +-----+ +-----+     +-----+

Requirements

  • Go 1.7 (using request's context)

Motivation

  • Needed requests to be cached
  • Needed bandwidth to be spread among N peers
  • Needed to cache HTTPS requests
  • Needed a lightweight infrastructure

So I couldn't go with existing solutions like Apache Traffic Server or Squid.

Process

When making a request through the pool...

  1. the requested url is hashed to determine which peer is responisble to proxy the request to the origin
  2. the peer is called, if the request is cached and valid, it is returned without contacting the origin
  3. if the request is not cached, the request is fetched from the origin and cached if cacheable before being returned back to the client

Example

pool := NewPool("http://10.0.1.1:3000", httpcache.NewMemoryCache())
pool.Set("http://10.0.1.1:3000", "http://10.0.1.2:3000", "http://10.0.1.3:3000")

// -then-

http.DefaultTransport = pool
http.Get("https://ajax.g[...]js/1.5.7/angular.min.js")

// -or-

http.DefaultClient = pool.Client()
http.Get("https://ajax.g[...]js/1.5.7/angular.min.js")

// -or-

c := pool.Client()
c.Get("https://ajax.g[...]js/1.5.7/angular.min.js")

// ...

http.ListenAndServe(":3000", pool.LocalProxy())

Licence

Apache 2.0 (see LICENSE and NOTICE)

Documentation

Overview

Package forwardcache provides a forward caching proxy that works across a set of peer processes. In simple terms, it is a distributed cache for HEAD and GET requests. It follows the HTTP RFC so it will only cache cacheable responses (like browsers do).

When an http request is made, a peer is chosen to handle the request according to the requested url's canonical owner.

If the content is cacheable as per the HTTP RFC, it will get cached on the peer and the response is then returned to the client. (thanks to github.com/gregjones/httpcache)

Note that the peers are not real HTTP proxies. They are themselves querying the origin servers and copying the response back to clients. It has the benefit of being able to cache TLS requests.

The result is that it is only suitable for use as a distributed 'private' cache since the requests are fully intercepted by the peers.

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultBufferPool = NewBufferPool(32 * 1024)

DefaultBufferPool is a pool which produces 32k buffers.

Functions

func WithBufferPool

func WithBufferPool(b httputil.BufferPool) func(*Peer)

WithBufferPool lets you configure a custom buffer pool. Defaults to not using a buffer pool.

func WithCache

func WithCache(c httpcache.Cache) func(*Peer)

WithCache lets you use a custom httpcache.Cache. Defaults to httpcache.MemoryCache.

func WithClient added in v1.0.1

func WithClient(c *Client) func(*Peer)

WithClient lets you configure a custom pool client. Defaults to NewClient(). If a Client is not specified upon Peer creation, SetPool(...) must be called to set the list of peers.

func WithClientTransport added in v1.0.1

func WithClientTransport(t http.RoundTripper) func(*Client)

WithClientTransport lets you configure a custom transport used between the local client and the proxies. Defaults to http.DefaultTransport.

func WithDefaultBufferPool

func WithDefaultBufferPool(b httputil.BufferPool) func(*Peer)

WithDefaultBufferPool lets you use the default 32k buffer pool. Defaults to not using a buffer pool.

func WithHashFn added in v1.0.1

func WithHashFn(h consistenthash.Hash) func(*Client)

WithHashFn specifies the hash function of the consistent hash. Defaults to crc32.ChecksumIEEE.

func WithPath added in v1.0.1

func WithPath(p string) func(*Client)

WithPath specifies the HTTP path that will serve proxy requests. Defaults to "/proxy".

func WithPeerTransport

func WithPeerTransport(t http.RoundTripper) func(*Peer)

WithPeerTransport lets you configure a custom transport used between the local peer and origins. Defaults to http.DefaultTransport.

func WithPool

func WithPool(peers ...string) func(*Client)

WithPool lets you configure the client's list of peers. Defaults to nil. See Client.SetPool(...).

func WithReplicas added in v1.0.1

func WithReplicas(r int) func(*Client)

WithReplicas specifies the number of key replicas on the consistent hash. Defaults to 50.

Types

type BufferPool

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

BufferPool uses sync.Pool for getting and returning temporary byte slices.

func NewBufferPool

func NewBufferPool(bufSize int) *BufferPool

NewBufferPool creates a new BufferPool.

func (*BufferPool) Get

func (p *BufferPool) Get() []byte

Get gets a buffer from the pool.

func (*BufferPool) Put

func (p *BufferPool) Put(b []byte)

Put puts back a buffer to the pool.

type Client added in v1.0.1

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

Client represents a nonparticipating client in the pool. It delegates requests to the responsible peer.

func NewClient

func NewClient(options ...func(*Client)) *Client

NewClient creates a Client.

Example
client := NewClient(WithPool("http://10.0.1.1:3000", "http://10.0.1.2:3000"))

// -then-

http.DefaultTransport = client
http.Get("https://...js/1.5.7/angular.min.js")

// -or-

http.DefaultClient = client.HTTPClient()
http.Get("https://...js/1.5.7/angular.min.js")

// -or-

c := client.HTTPClient()
c.Get("https://...js/1.5.7/angular.min.js")
Output:

func (*Client) HTTPClient added in v1.0.1

func (c *Client) HTTPClient() *http.Client

HTTPClient returns an http.Client that uses the Client as its transport.

func (*Client) RoundTrip added in v1.0.1

func (c *Client) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip makes the request go through one of the peer. Since Client implements the Roundtripper interface, it can be used as a transport.

func (*Client) SetPool

func (c *Client) SetPool(peers ...string)

SetPool updates the client's peers list. Each peer should be a valid base URL, for example "http://example.net:8000".

type Peer

type Peer struct {
	*Client
	// contains filtered or unexported fields
}

Peer is a peer in the pool. It handles and cache the requests for the clients. It is also able to issue requests on its own to other peers when a resource belongs to it.

func NewPeer

func NewPeer(self string, options ...func(*Peer)) *Peer

NewPeer creates a Peer. The returned *Peer implements http.Handler and must be registered manually using http.Handle to serve local requests. See Handler().

Example
peer := NewPeer("http://10.0.1.1:3000")
peer.SetPool("http://10.0.1.1:3000", "http://10.0.1.2:3000")

// -or-

client := NewClient(WithPool("http://10.0.1.1:3000", "http://10.0.1.2:3000"))
peer2 := NewPeer("http://10.0.1.1:3000", WithClient(client))

// -then-

http.DefaultTransport = peer
http.Get("https://...js/1.5.7/angular.min.js")

// -or-

http.DefaultClient = peer.HTTPClient()
http.Get("https://...js/1.5.7/angular.min.js")

// -or-

c := peer2.HTTPClient()
c.Get("https://...js/1.5.7/angular.min.js")

// ...

http.ListenAndServe(":3000", peer.Handler())
Output:

func (*Peer) Handler

func (p *Peer) Handler() http.Handler

Handler returns an http.Handler to be registered using http.Handle for the local Peer to serve requests.

func (*Peer) RoundTrip

func (p *Peer) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip makes the request go through one of the peer using its internal Client. If the local peer is targeted, it uses the local handler directly. Since Peer implements the Roundtripper interface, it can be used as a transport.

Directories

Path Synopsis
Package consistenthash provides an implementation of a ring hash.
Package consistenthash provides an implementation of a ring hash.
Package lru provides an lru cache algorithm over an existing cache.
Package lru provides an lru cache algorithm over an existing cache.

Jump to

Keyboard shortcuts

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