0
Fork 0
mirror of https://github.com/willnorris/imageproxy.git synced 2024-12-30 22:34:18 -05:00

replace in-memory cache with size-limited lrucache

Fixes #4
This commit is contained in:
Will Norris 2017-09-17 11:00:49 +00:00
parent db55cb60f8
commit a57047ff22
2 changed files with 33 additions and 4 deletions

View file

@ -94,8 +94,11 @@ you should see a 500px square coder octocat.
By default, the imageproxy command does not cache responses, but caching can be By default, the imageproxy command does not cache responses, but caching can be
enabled using the `-cache` flag. It supports the following values: enabled using the `-cache` flag. It supports the following values:
- `memory` - uses an in-memory cache. (This can exhaust your system's - `memory` - uses an in-memory LRU cache. By default, this is limited to
available memory and is not recommended for production systems) 100mb. To customize the size of the cache or the max age for cached items,
use the format `memory:size:age` where size is measured in mb and age is a
duration. For example, `memory:200:4h` will create a 200mb cache that will
cache items no longer than 4 hours.
- directory on local disk (e.g. `/tmp/imageproxy`) - will cache images - directory on local disk (e.g. `/tmp/imageproxy`) - will cache images
on disk on disk
- s3 URL (e.g. `s3://region/bucket-name/optional-path-prefix`) - will cache - s3 URL (e.g. `s3://region/bucket-name/optional-path-prefix`) - will cache

View file

@ -23,12 +23,14 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"strconv"
"strings" "strings"
"time"
"github.com/PaulARoy/azurestoragecache" "github.com/PaulARoy/azurestoragecache"
"github.com/die-net/lrucache"
"github.com/diegomarangoni/gcscache" "github.com/diegomarangoni/gcscache"
"github.com/garyburd/redigo/redis" "github.com/garyburd/redigo/redis"
"github.com/gregjones/httpcache"
"github.com/gregjones/httpcache/diskcache" "github.com/gregjones/httpcache/diskcache"
rediscache "github.com/gregjones/httpcache/redis" rediscache "github.com/gregjones/httpcache/redis"
"github.com/peterbourgon/diskv" "github.com/peterbourgon/diskv"
@ -36,6 +38,8 @@ import (
"willnorris.com/go/imageproxy/internal/s3cache" "willnorris.com/go/imageproxy/internal/s3cache"
) )
const defaultMemorySize = 100
var addr = flag.String("addr", "localhost:8080", "TCP address to listen on") var addr = flag.String("addr", "localhost:8080", "TCP address to listen on")
var whitelist = flag.String("whitelist", "", "comma separated list of allowed remote hosts") var whitelist = flag.String("whitelist", "", "comma separated list of allowed remote hosts")
var referrers = flag.String("referrers", "", "comma separated list of allowed referring hosts") var referrers = flag.String("referrers", "", "comma separated list of allowed referring hosts")
@ -102,7 +106,7 @@ func parseCache() (imageproxy.Cache, error) {
} }
if *cache == "memory" { if *cache == "memory" {
return httpcache.NewMemoryCache(), nil *cache = fmt.Sprintf("memory:%d", defaultMemorySize)
} }
u, err := url.Parse(*cache) u, err := url.Parse(*cache)
@ -115,6 +119,8 @@ func parseCache() (imageproxy.Cache, error) {
return azurestoragecache.New("", "", u.Host) return azurestoragecache.New("", "", u.Host)
case "gcs": case "gcs":
return gcscache.New(u.String()), nil return gcscache.New(u.String()), nil
case "memory":
return lruCache(u.Opaque)
case "redis": case "redis":
conn, err := redis.DialURL(u.String(), redis.DialPassword(os.Getenv("REDIS_PASSWORD"))) conn, err := redis.DialURL(u.String(), redis.DialPassword(os.Getenv("REDIS_PASSWORD")))
if err != nil { if err != nil {
@ -130,6 +136,26 @@ func parseCache() (imageproxy.Cache, error) {
} }
} }
// lruCache creates an LRU Cache with the specified options of the form
// "maxSize:maxAge". maxSize is specified in megabytes, maxAge is a duration.
func lruCache(options string) (*lrucache.LruCache, error) {
parts := strings.SplitN(options, ":", 2)
size, err := strconv.ParseInt(parts[0], 10, 64)
if err != nil {
return nil, err
}
var age time.Duration
if len(parts) > 1 {
age, err = time.ParseDuration(parts[1])
if err != nil {
return nil, err
}
}
return lrucache.New(size*1e6, int64(age.Seconds())), nil
}
func diskCache(path string) *diskcache.Cache { func diskCache(path string) *diskcache.Cache {
d := diskv.New(diskv.Options{ d := diskv.New(diskv.Options{
BasePath: path, BasePath: path,