diff --git a/cmd/depviz/main.go b/cmd/depviz/main.go index 8ca4b5eb4..7805216e7 100644 --- a/cmd/depviz/main.go +++ b/cmd/depviz/main.go @@ -50,6 +50,7 @@ var ( serverGodmode = serverFlags.Bool("godmode", false, "enable dangerous API calls") serverWithPprof = serverFlags.Bool("with-pprof", false, "enable pprof endpoints") serverWithoutRecovery = serverFlags.Bool("without-recovery", false, "disable panic recovery (dev)") + serverWithoutCache = serverFlags.Bool("without-cache", false, "disable HTTP caching") runFlags = flag.NewFlagSet("run", flag.ExitOnError) runNoPull = runFlags.Bool("no-pull", false, "don't pull providers (graph only)") @@ -290,6 +291,7 @@ func execServer(args []string) error { ShutdownTimeout: *serverShutdownTimeout, WithPprof: *serverWithPprof, WithoutRecovery: *serverWithoutRecovery, + WithoutCache: *serverWithoutCache, Godmode: *serverGodmode, } svc, err = dvserver.New(ctx, store, schemaConfig, opts) diff --git a/go.mod b/go.mod index 8e7f41471..676df42e3 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/prometheus/procfs v0.0.7 // indirect github.com/rs/cors v1.7.0 github.com/treastech/logger v0.0.0-20180705232552-e381e9ecf2e3 + github.com/victorspringer/http-cache v0.0.0-20190721184638-fe78e97af707 go.uber.org/multierr v1.4.0 // indirect go.uber.org/zap v1.13.0 golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f // indirect diff --git a/go.sum b/go.sum index 365169395..26a79fb17 100644 --- a/go.sum +++ b/go.sum @@ -344,6 +344,8 @@ github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8 h1:7X4KYG3g github.com/tylertreat/BoomFilters v0.0.0-20181028192813-611b3dbe80e8/go.mod h1:OYRfF6eb5wY9VRFkXJH8FFBi3plw2v+giaIu7P054pM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/victorspringer/http-cache v0.0.0-20190721184638-fe78e97af707 h1:Pg/LJmFZnr+hlP9sohJKDaxi1nTSOPvGNo8dBBgRIkM= +github.com/victorspringer/http-cache v0.0.0-20190721184638-fe78e97af707/go.mod h1:V7CEaXWuLs0tH3DNWqJO+GVr8YgiAwRgBh76T4LNSPU= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= diff --git a/internal/dvserver/server.go b/internal/dvserver/server.go index 1d84517e3..a5ac0713c 100644 --- a/internal/dvserver/server.go +++ b/internal/dvserver/server.go @@ -22,6 +22,8 @@ import ( "github.com/oklog/run" "github.com/rs/cors" chilogger "github.com/treastech/logger" + cache "github.com/victorspringer/http-cache" + "github.com/victorspringer/http-cache/adapter/memory" "go.uber.org/zap" "google.golang.org/grpc" "moul.io/depviz/internal/chiutil" @@ -37,6 +39,7 @@ type Opts struct { WithoutRecovery bool WithPprof bool Godmode bool + WithoutCache bool } type Service interface { @@ -144,7 +147,6 @@ func New(ctx context.Context, h *cayley.Handle, schema *schema.Config, opts Opts r.Use(middleware.Timeout(opts.RequestTimeout)) r.Use(middleware.RealIP) r.Use(middleware.RequestID) - // FIXME: add caching gwmux := runtime.NewServeMux( runtime.WithMarshalerOption(runtime.MIMEWildcard, &gateway.JSONPb{ EmitDefaults: false, @@ -158,8 +160,31 @@ func New(ctx context.Context, h *cayley.Handle, schema *schema.Config, opts Opts return nil, fmt.Errorf("register service on gateway: %w", err) } + var handler http.Handler = gwmux + // api endpoints - r.Mount("/api", http.StripPrefix("/api", gwmux)) + if !opts.WithoutCache { + // FIXME: invalidate cache + memcached, err := memory.NewAdapter( + memory.AdapterWithAlgorithm(memory.LRU), + memory.AdapterWithCapacity(10000000), + ) + if err != nil { + return nil, fmt.Errorf("memory cache: %w", err) + } + + cacheClient, err := cache.NewClient( + cache.ClientWithAdapter(memcached), + cache.ClientWithTTL(10*time.Minute), + cache.ClientWithRefreshKey("opn"), + ) + if err != nil { + return nil, fmt.Errorf("cache client: %w", err) + } + + handler = cacheClient.Middleware(handler) + } + r.Mount("/api", http.StripPrefix("/api", handler)) // pprof endpoints if opts.WithPprof { diff --git a/internal/githubprovider/model.go b/internal/githubprovider/model.go index 1b66776b3..3fde81665 100644 --- a/internal/githubprovider/model.go +++ b/internal/githubprovider/model.go @@ -17,7 +17,7 @@ func fromIssues(issues []*github.Issue, logger *zap.Logger) (dvmodel.Batch, erro for _, issue := range issues { err := fromIssue(&batch, issue) if err != nil { - logger.Warn("failed to parse issue", zap.Error(err)) + logger.Warn("parse issue", zap.String("url", issue.GetHTMLURL()), zap.Error(err)) continue } }