docs: extend readme, add inline docs

This commit is contained in:
 Ilya Atamas 2019-04-22 18:56:32 +03:00
parent 778c92c3b9
commit 1d688d0263
8 changed files with 61 additions and 51 deletions

12
go.mod
View File

@ -3,22 +3,10 @@ module github.com/emeralt/npm-cache-proxy
go 1.12
require (
github.com/gin-contrib/gzip v0.0.1
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 // indirect
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7
github.com/gin-gonic/gin v1.3.0
github.com/go-redis/redis v6.15.2+incompatible
github.com/golang/protobuf v1.3.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/mattn/go-isatty v0.0.7 // indirect
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
github.com/stretchr/objx v0.2.0 // indirect
go.uber.org/zap v1.9.1
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480 // indirect
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6 // indirect
golang.org/x/sync v0.0.0-20190412183630-56d357773e84 // indirect
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

29
go.sum
View File

@ -1,11 +1,6 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY=
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3 h1:t8FVkw33L+wilf2QiWkw0UV77qRpcH/JHPKGpKa2E8g=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7 h1:v6rNWmMnVDBVMc1pUUSCTobu2p4BukiPMwoj0pLqBhA=
github.com/gin-contrib/zap v0.0.0-20190405225521-7c4b822813e7/go.mod h1:pQKeeey3PeRN2SbZe1jWiIkTJkylO9hL1K0Hf4Wbtt4=
github.com/gin-gonic/gin v1.3.0 h1:kCmZyPklC0gVdL728E6Aj20uYBJV93nj/TkwBTKhFbs=
@ -14,16 +9,9 @@ github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDA
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -32,11 +20,7 @@ github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 h1:EICbibRW4JNKMcY+LsWmuwob+CRS1BmdRdjphAm9mH4=
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
@ -45,25 +29,12 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a h1:XCr/YX7O0uxRkLq2k1ApNQMims9eCioF9UpzIPBDmuo=
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -8,7 +8,7 @@ import (
"strings"
)
// GetMetadata returns cached NPM response for a given package path
// GetMetadata returns cached NPM response for a given package path.
func (proxy Proxy) GetMetadata(name string, originalPath string, request *http.Request) ([]byte, error) {
options, err := proxy.GetOptions()
if err != nil {
@ -93,7 +93,7 @@ func (proxy Proxy) ListMetadata() ([]string, error) {
return deprefixedMetadata, nil
}
// PurgeMetadata deletes all cached packages
// PurgeMetadata deletes all cached packages.
func (proxy Proxy) PurgeMetadata() error {
options, err := proxy.GetOptions()
if err != nil {

View File

@ -6,26 +6,32 @@ import (
"github.com/go-redis/redis"
)
// DatabaseRedis implements Database interface for Redis database.
type DatabaseRedis struct {
Client *redis.Client
}
// Get returns data by key.
func (db DatabaseRedis) Get(key string) (string, error) {
return db.Client.Get(key).Result()
}
// Set stores value identified by key with expiration timeout.
func (db DatabaseRedis) Set(key string, value string, expiration time.Duration) error {
return db.Client.Set(key, value, expiration).Err()
}
// Delete deletes data by key.
func (db DatabaseRedis) Delete(key string) error {
return db.Client.Del(key).Err()
}
// Keys returns stored keys filtered by prefix.
func (db DatabaseRedis) Keys(prefix string) ([]string, error) {
return db.Client.Keys(prefix + "*").Result()
}
// Health returns an error if database connection cannot be estabilished.
func (db DatabaseRedis) Health() error {
return db.Client.Ping().Err()
}

5
proxy/doc.go Normal file
View File

@ -0,0 +1,5 @@
//
// Package proxy implements a HTTP caching proxy for Node package registry (NPM).
// See https://github.com/emeralt/npm-cache-proxy/ for more information about proxy.
//
package proxy // import "https://github.com/emeralt/npm-cache-proxy/proxy"

View File

@ -5,6 +5,8 @@ import (
"time"
)
// Proxy is the proxy instance, it contains Database and HttpClient as static options
// and GetOptions as dynamic options provider
type Proxy struct {
Database Database
HttpClient *http.Client
@ -12,12 +14,16 @@ type Proxy struct {
GetOptions func() (Options, error)
}
// Options provides dynamic options for Proxy.
// This can be used for namespace separation,
// allowing multiple users use the same proxy instance simultaneously.
type Options struct {
DatabasePrefix string
DatabaseExpiration time.Duration
UpstreamAddress string
}
// Database provides interface for data storage.
type Database interface {
Get(key string) (string, error)
Set(key string, value string, ttl time.Duration) error

View File

@ -13,15 +13,16 @@ type ServerOptions struct {
ListenAddress string
}
// Server creates http proxy server
func (proxy Proxy) Server(options ServerOptions) *http.Server {
router := gin.New()
logger, _ := zap.NewProduction()
router.Use(ginzap.Ginzap(logger, time.RFC3339, true))
router.GET("/:scope/:name", proxy.GetPackageHandler)
router.GET("/:scope", proxy.GetPackageHandler)
router.NoRoute(proxy.NoRouteHandler)
router.GET("/:scope/:name", proxy.getPackageHandler)
router.GET("/:scope", proxy.getPackageHandler)
router.NoRoute(proxy.noRouteHandler)
return &http.Server{
Handler: router,
@ -29,7 +30,7 @@ func (proxy Proxy) Server(options ServerOptions) *http.Server {
}
}
func (proxy Proxy) GetPackageHandler(c *gin.Context) {
func (proxy Proxy) getPackageHandler(c *gin.Context) {
var name string
if c.Param("name") != "" {
name = c.Param("scope") + "/" + c.Param("name")
@ -47,7 +48,7 @@ func (proxy Proxy) GetPackageHandler(c *gin.Context) {
}
}
func (proxy Proxy) NoRouteHandler(c *gin.Context) {
func (proxy Proxy) noRouteHandler(c *gin.Context) {
if c.Request.URL.Path == "/" {
err := proxy.Database.Health()

View File

@ -3,16 +3,26 @@
![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/emeralt/npm-cache-proxy.svg?style=for-the-badge)
- [npm-cache-proxy](#npm-cache-proxy)
- [Download](#download)
- [Quick start](#quick-start)
- [Deployment](#deployment)
- [Usage](#usage)
- [`ncp`](#ncp)
- [`ncp list`](#ncp-list)
- [`ncp purge`](#ncp-purge)
- [Programmatic usage](#programmatic-usage)
- [Example](#example)
- [Benchmark](#benchmark)
- [License](#license)
## Download
You can download binary for your platform on the [Releases](https://github.com/emeralt/npm-cache-proxy/releases) page. Alternatively, you can use [Docker Image](https://cloud.docker.com/u/emeralt/repository/docker/emeralt/npm-cache-proxy).
## Quick start
Release binaries for different platforms can be downloaded on the [Releases](https://github.com/emeralt/npm-cache-proxy/releases) page. Also, [Docker Image](https://cloud.docker.com/u/emeralt/repository/docker/emeralt/npm-cache-proxy) is provided.
```bash
docker run -e REDIS_ADDRESS=host.docker.internal:6379 -p 8080:8080 -it emeralt/npm-cache-proxy
```
## Deployment
NCP can be deployed using Kubernetes, Docker Compose or any other container orchestration platform. NCP supports running indefinite amount of instances simultaneously.
## Usage
@ -40,7 +50,13 @@ List cached packages.
Purge cached packages.
## Programmatic usage
Along with the CLI, go package is provided. Documentation is available on [godoc.org](https://godoc.org/github.com/emeralt/npm-cache-proxy/proxy).
```bash
go get -u github.com/emeralt/npm-cache-proxy/proxy
```
### Example
```golang
package main
@ -75,6 +91,23 @@ func main() {
}
```
## Benchmark
```bash
# GOMAXPROCS=1 GIN_MODE=release ncp --listen localhost:8080
$ go-wrk -c 100 -d 5 http://localhost:8080/ascii
Running 5s test @ http://localhost:8080/ascii
100 goroutine(s) running concurrently
33321 requests in 5.00537759s, 212.69MB read
Requests/sec: 6657.04
Transfer/sec: 42.49MB
Avg Req Time: 15.02169ms
Fastest Request: 230.514µs
Slowest Request: 571.420487ms
Number of Errors: 0
```
## License
[MIT](./license)