Skip to content

Commit

Permalink
feat: add project info cache size, ttl config
Browse files Browse the repository at this point in the history
  • Loading branch information
blurfx committed Jul 31, 2023
1 parent 378576d commit 82aa9f2
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 9 deletions.
14 changes: 14 additions & 0 deletions cmd/yorkie/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var (
authWebhookMaxWaitInterval time.Duration
authWebhookCacheAuthTTL time.Duration
authWebhookCacheUnauthTTL time.Duration
projectInfoCacheTTL time.Duration

etcdEndpoints []string
etcdDialTimeout time.Duration
Expand All @@ -72,6 +73,7 @@ func newServerCmd() *cobra.Command {
conf.Backend.AuthWebhookMaxWaitInterval = authWebhookMaxWaitInterval.String()
conf.Backend.AuthWebhookCacheAuthTTL = authWebhookCacheAuthTTL.String()
conf.Backend.AuthWebhookCacheUnauthTTL = authWebhookCacheUnauthTTL.String()
conf.Backend.ProjectInfoCacheTTL = projectInfoCacheTTL.String()

conf.Housekeeping.Interval = housekeepingInterval.String()

Expand Down Expand Up @@ -337,6 +339,18 @@ func init() {
server.DefaultAuthWebhookCacheUnauthTTL,
"TTL value to set when caching unauthorized webhook response.",
)
cmd.Flags().IntVar(
&conf.Backend.ProjectInfoCacheSize,
"project-info-cache-size",
server.DefaultProjectInfoCacheSize,
"The cache size of the project info.",
)
cmd.Flags().DurationVar(
&projectInfoCacheTTL,
"project-info-cache-ttl",
server.DefaultProjectInfoCacheTTL,
"TTL value to set when caching project info.",
)
cmd.Flags().StringVar(
&conf.Backend.Hostname,
"hostname",
Expand Down
25 changes: 25 additions & 0 deletions server/backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ type Config struct {
// AuthWebhookCacheUnauthTTL is the TTL value to set when caching the unauthorized result.
AuthWebhookCacheUnauthTTL string `yaml:"AuthWebhookCacheUnauthTTL"`

// ProjectInfoCacheSize is the cache size of the project info.
ProjectInfoCacheSize int `yaml:"ProjectInfoCacheSize"`

// ProjectInfoCacheTTL is the TTL value to set when caching the project info.
ProjectInfoCacheTTL string `yaml:"ProjectInfoCacheTTL"`

// Hostname is yorkie server hostname. hostname is used by metrics.
Hostname string `yaml:"Hostname"`
}
Expand Down Expand Up @@ -108,6 +114,14 @@ func (c *Config) Validate() error {
)
}

if _, err := time.ParseDuration(c.ProjectInfoCacheTTL); err != nil {
return fmt.Errorf(
`invalid argument "%s" for "--project-info-cache-ttl" flag: %w`,
c.ProjectInfoCacheTTL,
err,
)
}

return nil
}

Expand Down Expand Up @@ -154,3 +168,14 @@ func (c *Config) ParseAuthWebhookCacheUnauthTTL() time.Duration {

return result
}

// ParseProjectInfoCacheTTL returns TTL for project info cache.
func (c *Config) ParseProjectInfoCacheTTL() time.Duration {
result, err := time.ParseDuration(c.ProjectInfoCacheTTL)
if err != nil {
fmt.Fprintln(os.Stderr, "parse project info cache ttl: %w", err)
os.Exit(1)
}

return result
}
5 changes: 5 additions & 0 deletions server/backend/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestConfig(t *testing.T) {
AuthWebhookMaxWaitInterval: "0ms",
AuthWebhookCacheAuthTTL: "10s",
AuthWebhookCacheUnauthTTL: "10s",
ProjectInfoCacheTTL: "1h",
}
assert.NoError(t, validConf.Validate())

Expand All @@ -49,5 +50,9 @@ func TestConfig(t *testing.T) {
conf4 := validConf
conf4.AuthWebhookCacheUnauthTTL = "s"
assert.Error(t, conf4.Validate())

conf5 := validConf
conf5.ProjectInfoCacheTTL = "1 hour"
assert.Error(t, conf5.Validate())
})
}
10 changes: 10 additions & 0 deletions server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ const (
DefaultAuthWebhookCacheSize = 5000
DefaultAuthWebhookCacheAuthTTL = 10 * time.Second
DefaultAuthWebhookCacheUnauthTTL = 10 * time.Second
DefaultProjectInfoCacheSize = 256
DefaultProjectInfoCacheTTL = time.Hour

DefaultHostname = ""
)
Expand Down Expand Up @@ -201,6 +203,14 @@ func (c *Config) ensureDefaultValue() {
c.Backend.AuthWebhookCacheUnauthTTL = DefaultAuthWebhookCacheUnauthTTL.String()
}

if c.Backend.ProjectInfoCacheSize == 0 {
c.Backend.ProjectInfoCacheSize = DefaultProjectInfoCacheSize
}

if c.Backend.ProjectInfoCacheTTL == "" {
c.Backend.ProjectInfoCacheTTL = DefaultProjectInfoCacheTTL.String()
}

if c.Mongo != nil {
if c.Mongo.ConnectionURI == "" {
c.Mongo.ConnectionURI = DefaultMongoConnectionURI
Expand Down
6 changes: 6 additions & 0 deletions server/config.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ Backend:
# AuthWebhookCacheUnauthTTL is the TTL value to set when caching the unauthorized result.
AuthWebhookCacheUnauthTTL: "10s"

# ProjectInfoCacheSize is the size of the project info cache.
ProjectInfoCacheSize: 256

# ProjectInfoCacheTTL is the TTL value to set when caching the project info.
ProjectInfoCacheTTL: "1h"

# Hostname is the hostname of the server. If not provided, the hostname will be
# determined automatically by the OS (Optional, default: os.Hostname()).
Hostname: ""
Expand Down
4 changes: 4 additions & 0 deletions server/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,9 @@ func TestNewConfigFromFile(t *testing.T) {
authWebhookCacheUnauthTTL, err := time.ParseDuration(conf.Backend.AuthWebhookCacheUnauthTTL)
assert.NoError(t, err)
assert.Equal(t, authWebhookCacheUnauthTTL, server.DefaultAuthWebhookCacheUnauthTTL)

projectInfoCacheTTL, err := time.ParseDuration(conf.Backend.ProjectInfoCacheTTL)
assert.NoError(t, err)
assert.Equal(t, projectInfoCacheTTL, server.DefaultProjectInfoCacheTTL)
})
}
13 changes: 4 additions & 9 deletions server/rpc/interceptors/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/yorkie-team/yorkie/pkg/cache"
"github.com/yorkie-team/yorkie/server/logging"

grpcmiddleware "github.com/grpc-ecosystem/go-grpc-middleware"
"google.golang.org/grpc"
Expand All @@ -33,15 +29,14 @@ import (
grpcstatus "google.golang.org/grpc/status"

"github.com/yorkie-team/yorkie/api/types"
"github.com/yorkie-team/yorkie/pkg/cache"
"github.com/yorkie-team/yorkie/server/backend"
"github.com/yorkie-team/yorkie/server/logging"
"github.com/yorkie-team/yorkie/server/projects"
"github.com/yorkie-team/yorkie/server/rpc/grpchelper"
"github.com/yorkie-team/yorkie/server/rpc/metadata"
)

const projectInfoCacheSize = 256
const projectInfoCacheTTL = time.Hour

// ContextInterceptor is an interceptor for building additional context.
type ContextInterceptor struct {
backend *backend.Backend
Expand All @@ -50,7 +45,7 @@ type ContextInterceptor struct {

// NewContextInterceptor creates a new instance of ContextInterceptor.
func NewContextInterceptor(be *backend.Backend) *ContextInterceptor {
projectInfoCache, err := cache.NewLRUExpireCache[string, *types.Project](projectInfoCacheSize)
projectInfoCache, err := cache.NewLRUExpireCache[string, *types.Project](be.Config.ProjectInfoCacheSize)
if err != nil {
logging.DefaultLogger().Fatal("Failed to create project info cache: %v", err)
}
Expand Down Expand Up @@ -170,7 +165,7 @@ func (i *ContextInterceptor) buildContext(ctx context.Context) (context.Context,
if err != nil {
return nil, grpchelper.ToStatusError(err)
}
i.projectInfoCache.Add(cacheKey, project, projectInfoCacheTTL)
i.projectInfoCache.Add(cacheKey, project, i.backend.Config.ParseProjectInfoCacheTTL())
ctx = projects.With(ctx, project)
}

Expand Down
2 changes: 2 additions & 0 deletions server/rpc/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func TestMain(m *testing.M) {
ClientDeactivateThreshold: helper.ClientDeactivateThreshold,
SnapshotThreshold: helper.SnapshotThreshold,
AuthWebhookCacheSize: helper.AuthWebhookSize,
ProjectInfoCacheSize: helper.ProjectInfoCacheSize,
ProjectInfoCacheTTL: helper.ProjectInfoCacheTTL.String(),
AdminTokenDuration: helper.AdminTokenDuration,
}, &mongo.Config{
ConnectionURI: helper.MongoConnectionURI,
Expand Down
4 changes: 4 additions & 0 deletions test/helper/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ var (
AuthWebhookSize = 100
AuthWebhookCacheAuthTTL = 10 * gotime.Second
AuthWebhookCacheUnauthTTL = 10 * gotime.Second
ProjectInfoCacheSize = 256
ProjectInfoCacheTTL = 5 * gotime.Second

MongoConnectionURI = "mongodb://localhost:27017"
MongoConnectionTimeout = "5s"
Expand Down Expand Up @@ -238,6 +240,8 @@ func TestConfig() *server.Config {
AuthWebhookCacheSize: AuthWebhookSize,
AuthWebhookCacheAuthTTL: AuthWebhookCacheAuthTTL.String(),
AuthWebhookCacheUnauthTTL: AuthWebhookCacheUnauthTTL.String(),
ProjectInfoCacheSize: ProjectInfoCacheSize,
ProjectInfoCacheTTL: ProjectInfoCacheTTL.String(),
},
Mongo: &mongo.Config{
ConnectionURI: MongoConnectionURI,
Expand Down
2 changes: 2 additions & 0 deletions test/integration/auth_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ func TestProjectAuthWebhook(t *testing.T) {
)
assert.NoError(t, err)

projectInfoCacheTTL := 5 * time.Second
time.Sleep(projectInfoCacheTTL)
cli, err := client.Dial(
svr.RPCAddr(),
client.WithAPIKey(project.PublicKey),
Expand Down

0 comments on commit 82aa9f2

Please sign in to comment.