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 | 
| +} |