Skip to content

Commit

Permalink
fix: allocate less memory to the cache by default
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed Jan 5, 2021
1 parent 86b5848 commit 0b14a2e
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 50 deletions.
34 changes: 24 additions & 10 deletions caddy/caddy.go
Expand Up @@ -50,12 +50,12 @@ type Mercure struct {
// Allow subscribers with no valid JWT.
Anonymous bool `json:"anonymous,omitempty"`

// Enable the demo.
Demo string `json:"demo,omitempty"`

// Dispatch updates when subscriptions are created or terminated
Subscriptions bool `json:"subscriptions,omitempty"`

// Enable the demo.
Demo string `json:"demo,omitempty"`

// Maximum duration before closing the connection, defaults to 600s, set to 0 to disable.
WriteTimeout caddy.Duration `json:"write_timeout,omitempty"`

Expand All @@ -80,8 +80,11 @@ type Mercure struct {
// Transport to use.
TransportURL string `json:"transport_url,omitempty"`

// The approximate cache size in bytes, defaults to ~1GB, set to 0 to disable.
CacheSizeApprox *int64 `json:"cache_size_approx,omitempty"`
// Number of cache counters, defaults to 6e7, set to 0 to disable the cache. See https://github.com/dgraph-io/ristretto for details.
CacheNumCounters *int64 `json:"cache_max_counters,omitempty"`

// Maximum cache cost, defaults to 100MB, set to 0 to disable the cache. See https://github.com/dgraph-io/ristretto for details.
CacheMaxCost *int64 `json:"cache_max_cost,omitempty"`

hub *mercure.Hub
logger *zap.Logger
Expand Down Expand Up @@ -177,8 +180,8 @@ func (m *Mercure) Provision(ctx caddy.Context) error { //nolint:funlen
if len(m.CORSOrigins) > 0 {
opts = append(opts, mercure.WithCORSOrigins(m.CORSOrigins))
}
if m.CacheSizeApprox != nil {
opts = append(opts, mercure.WithCacheSizeApprox(*m.CacheSizeApprox))
if m.CacheNumCounters != nil && m.CacheMaxCost != nil {
opts = append(opts, mercure.WithCacheConfig(*m.CacheNumCounters, *m.CacheMaxCost))
}

h, err := mercure.NewHub(opts...)
Expand Down Expand Up @@ -304,17 +307,28 @@ func (m *Mercure) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { //nolint:fu

m.TransportURL = d.Val()

case "cache_size_approx":
case "cache":
if !d.NextArg() {
return d.ArgErr()
}

v, err := strconv.ParseInt(d.Val(), 10, 64)
if err != nil {
return err //nolint:wrapcheck
}

m.CacheNumCounters = &v

if !d.NextArg() {
return d.ArgErr()
}

s, err := strconv.ParseInt(d.Val(), 10, 64)
v, err = strconv.ParseInt(d.Val(), 10, 64)
if err != nil {
return err //nolint:wrapcheck
}

m.CacheSizeApprox = &s
m.CacheMaxCost = &v
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions caddy/caddy_test.go
Expand Up @@ -33,7 +33,6 @@ func TestMercure(t *testing.T) {
mercure {
anonymous
publisher_jwt !ChangeMe!
cache_size_approx 0
}
respond 404
Expand Down Expand Up @@ -110,7 +109,6 @@ func TestJWTPlaceholders(t *testing.T) {
mercure {
anonymous
publisher_jwt {env.TEST_JWT_KEY} {env.TEST_JWT_ALG}
cache_size_approx 0
}
respond 404
Expand Down
8 changes: 4 additions & 4 deletions caddy/go.mod
Expand Up @@ -6,12 +6,12 @@ replace github.com/dunglas/mercure => ../

require (
github.com/Masterminds/sprig/v3 v3.2.0 // indirect
github.com/antlr/antlr4 v0.0.0-20210104210359-82113bde9b3f // indirect
github.com/antlr/antlr4 v0.0.0-20210105192210-19ec50f38aad // indirect
github.com/caddyserver/caddy/v2 v2.3.0
github.com/dgraph-io/badger v1.6.2 // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/dunglas/mercure v0.11.0
github.com/dunglas/mercure v0.11.0-rc.2
github.com/golang/snappy v0.0.2 // indirect
github.com/google/uuid v1.1.4 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
Expand All @@ -30,11 +30,11 @@ require (
github.com/smallstep/nosql v0.3.2 // indirect
github.com/stretchr/testify v1.6.1
github.com/urfave/cli v1.22.5 // indirect
github.com/yuin/goldmark v1.3.0 // indirect
github.com/yuin/goldmark v1.3.1 // indirect
go.step.sm/crypto v0.8.0 // indirect
go.uber.org/zap v1.16.0
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d // indirect
google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
google.golang.org/grpc v1.33.2 // indirect
howett.net/plist v0.0.0-20201203080718-1454fab16a06 // indirect
)
12 changes: 6 additions & 6 deletions caddy/go.sum
Expand Up @@ -110,8 +110,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f h1:0cEys61Sr2hUBEXfNV8eyQP01oZuBgoMeHunebPirK8=
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
github.com/antlr/antlr4 v0.0.0-20210104210359-82113bde9b3f h1:Hkj3C0JjN9BznWaZOWFqZ4XgtHgz+6+YsmhgkMJl2/g=
github.com/antlr/antlr4 v0.0.0-20210104210359-82113bde9b3f/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
github.com/antlr/antlr4 v0.0.0-20210105192210-19ec50f38aad h1:tAKK/dpHhWy7O1rkBwSzUGqdt+iM/XQfgKpoPcm8h7U=
github.com/antlr/antlr4 v0.0.0-20210105192210-19ec50f38aad/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
Expand Down Expand Up @@ -928,8 +928,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.0 h1:DRvEHivhJ1fQhZbpmttnonfC674RycyZGE/5IJzDKgg=
github.com/yuin/goldmark v1.3.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.3.1 h1:eVwehsLsZlCJCwXyGLgg+Q4iFWE/eTIMG0e8waCmm/I=
github.com/yuin/goldmark v1.3.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSxtAiQNh3zgHJpdpkpVYjTPqRE3P6UZCOPa1nRDio=
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE=
Expand Down Expand Up @@ -1372,8 +1372,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d h1:HV9Z9qMhQEsdlvxNFELgQ11RkMzO3CMkjEySjCtuLes=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 h1:Zk6zlGXdtYdcY5TL+VrbTfmifvk3VvsXopCpszsHPBA=
google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
Expand Down
2 changes: 1 addition & 1 deletion caddy/mercure/main.go
Expand Up @@ -4,7 +4,7 @@ package main
import (
caddycmd "github.com/caddyserver/caddy/v2/cmd"

// plug in Caddy modules here
// plug in Caddy modules here.
_ "github.com/caddyserver/caddy/v2/modules/standard"
_ "github.com/dunglas/mercure/caddy"
)
Expand Down
2 changes: 1 addition & 1 deletion docs/hub/config.md
Expand Up @@ -44,7 +44,7 @@ The following Mercure-specific directives are available:
| `dispatch_timeout <duration>` | maximum duration of the dispatch of a single update, set to `0s` disable | `5s` |
| `write_timeout <duration>` | maximum duration before closing the connection, set to `0s` disable | `600s` |
| `demo [<assets-path>]` | enable the demo mode and the UI | |
| `cache_size_approx <size>` | approximate cache size in bytes, set to `0` to disable | ~1GB |
| `cache <num-counters> <max-cost>` | cache configuration (see [Ristretto's docs](https://github.com/dgraph-io/ristretto)), set to 0 to disable the cache | `6e7` `1e8` (100MB) |

See also [the list of built-in Caddyfile directives](https://caddyserver.com/docs/caddyfile/directives).

Expand Down
51 changes: 27 additions & 24 deletions hub.go
Expand Up @@ -169,10 +169,11 @@ func WithTransport(t Transport) Option {
}
}

// WithCacheSizeApprox sets the approximate cache size in bytes, defaults to ~1GB, set to 0 to disable.
func WithCacheSizeApprox(s int64) Option {
// WithCacheConfig see https://github.com/dgraph-io/ristretto, defaults to 6e7 counters and 100MB of max cost, set values to 0 to disable.
func WithCacheConfig(numCounters, maxCost int64) Option {
return func(o *opt) error {
o.cacheSizeApprox = s
o.cacheNumCounters = numCounters
o.cacheMaxCost = maxCost

return nil
}
Expand All @@ -187,22 +188,23 @@ type jwtConfig struct {
//
// If you change this, also update the Caddy module and the documentation.
type opt struct {
transport Transport
anonymous bool
debug bool
subscriptions bool
uiPath string
logger Logger
writeTimeout time.Duration
dispatchTimeout time.Duration
heartbeat time.Duration
publisherJWT *jwtConfig
subscriberJWT *jwtConfig
metrics Metrics
allowedHosts []string
publishOrigins []string
corsOrigins []string
cacheSizeApprox int64
transport Transport
anonymous bool
debug bool
subscriptions bool
uiPath string
logger Logger
writeTimeout time.Duration
dispatchTimeout time.Duration
heartbeat time.Duration
publisherJWT *jwtConfig
subscriberJWT *jwtConfig
metrics Metrics
allowedHosts []string
publishOrigins []string
corsOrigins []string
cacheNumCounters int64
cacheMaxCost int64
}

// Hub stores channels with clients currently subscribed and allows to dispatch updates.
Expand All @@ -220,8 +222,9 @@ type Hub struct {
// NewHub creates a new Hub instance.
func NewHub(options ...Option) (*Hub, error) {
opt := &opt{
writeTimeout: 600 * time.Second,
cacheSizeApprox: 1 << 30, // 1GB
writeTimeout: 600 * time.Second,
cacheNumCounters: 6e7, // gather stats to find the best default values
cacheMaxCost: 1e8,
}

for _, o := range options {
Expand Down Expand Up @@ -258,11 +261,11 @@ func NewHub(options ...Option) (*Hub, error) {
}

var cache *ristretto.Cache
if opt.cacheSizeApprox != 0 {
if opt.cacheNumCounters != 0 {
var err error
cache, err = ristretto.NewCache(&ristretto.Config{
NumCounters: opt.cacheSizeApprox * 10,
MaxCost: opt.cacheSizeApprox,
NumCounters: opt.cacheNumCounters,
MaxCost: opt.cacheMaxCost,
BufferItems: 64,
})
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions hub_test.go
Expand Up @@ -28,7 +28,6 @@ func TestNewHubWithConfig(t *testing.T) {
h, err := NewHub(
WithPublisherJWT([]byte("foo"), jwt.SigningMethodHS256.Name),
WithSubscriberJWT([]byte("bar"), jwt.SigningMethodHS256.Name),
WithCacheSizeApprox(0),
)
require.NotNil(t, h)
require.Nil(t, err)
Expand Down Expand Up @@ -72,7 +71,7 @@ func createDummy(options ...Option) *Hub {
WithPublisherJWT([]byte("publisher"), jwt.SigningMethodHS256.Name),
WithSubscriberJWT([]byte("subscriber"), jwt.SigningMethodHS256.Name),
WithLogger(zap.NewNop()),
WithCacheSizeApprox(0),
WithCacheConfig(0, 0),
},
options...,
)
Expand Down

0 comments on commit 0b14a2e

Please sign in to comment.