Chromium Code Reviews| Index: logdog/server/service/config/cache.go |
| diff --git a/logdog/server/service/config/cache.go b/logdog/server/service/config/cache.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5f2db7ab3237a8c715697b114c6177e3e534c504 |
| --- /dev/null |
| +++ b/logdog/server/service/config/cache.go |
| @@ -0,0 +1,63 @@ |
| +// Copyright 2017 The LUCI Authors. All rights reserved. |
| +// Use of this source code is governed under the Apache License, Version 2.0 |
| +// that can be found in the LICENSE file. |
| + |
| +package config |
| + |
| +import ( |
| + "context" |
| + "time" |
| + |
| + "github.com/luci/luci-go/common/data/caching/proccache" |
| + "github.com/luci/luci-go/common/sync/mutexpool" |
| + "github.com/luci/luci-go/luci_config/common/cfgtypes" |
| + "github.com/luci/luci-go/luci_config/server/cfgclient" |
| + "github.com/luci/luci-go/luci_config/server/cfgclient/textproto" |
| + |
| + "github.com/golang/protobuf/proto" |
| +) |
| + |
| +// ProcCache is an in-memory configuration cache. Unlike the "proccache" config |
| +// Backend, this stores the unmarshaled configuration object in-memory. |
| +type ProcCache struct { |
| + // Lifetime is the lifetime of the cached object. |
|
iannucci
2017/01/21 00:27:05
of each cached object? This can cache more than on
dnj
2017/01/21 01:53:06
Yeah this is just the cache. Really, behind the sc
|
| + Lifetime time.Duration |
| + |
| + mutexes mutexpool.P |
| +} |
| + |
| +// GetTextProto returns an unmarshalled configuration service text protobuf |
| +// message. |
| +// |
| +// If the message is not currently in the process cache, it will be fetched from |
| +// the config service and cached prior to being returned. |
| +func (pc *ProcCache) GetTextProto(c context.Context, cset cfgtypes.ConfigSet, path string, msg proto.Message) ( |
| + proto.Message, error) { |
| + |
| + key := procCacheKey{cset, path} |
| + |
| + // Load the value from our cache. First, though, take out a lock on this |
| + // specific config key. This will prevent multiple concurrent accesses from |
| + // slamming the config service, particularly at startup. |
| + var v interface{} |
| + var err error |
| + pc.mutexes.WithMutex(key, func() { |
| + v, err = proccache.GetOrMake(c, key, func() (interface{}, time.Duration, error) { |
| + // Not in cache or expired. Reload... |
| + if err := cfgclient.Get(c, cfgclient.AsService, cset, path, textproto.Message(msg), nil); err != nil { |
| + return nil, 0, err |
| + } |
| + return msg, pc.Lifetime, nil |
| + }) |
| + }) |
| + |
| + if err != nil { |
| + return nil, err |
| + } |
| + return v.(proto.Message), nil |
| +} |
| + |
| +type procCacheKey struct { |
| + cset cfgtypes.ConfigSet |
|
iannucci
2017/01/21 00:27:05
this is a `string` underlying type, right?
dnj
2017/01/21 01:53:06
Yep
|
| + path string |
| +} |