Skip to content

Commit fd791f1

Browse files
authored
Merge pull request #249 from rstudio/jmw/do-not-cache-errs
fix: do not attempt to cache object when there is an error
2 parents fd9d6c7 + 5de4d9a commit fd791f1

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

pkg/rscache/memory_backed_file_cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (mbfc *MemoryBackedFileCache) Get(ctx context.Context, resolver ResolverSpe
8989

9090
ptr = mbfc.fc.Get(ctx, resolver)
9191

92-
if resolver.CacheInMemory && mbfc.mc != nil && mbfc.mc.Enabled() && ptr.GetSize() < mbfc.maxMemoryPerObject {
92+
if resolver.CacheInMemory && mbfc.mc != nil && mbfc.mc.Enabled() && ptr.Err == nil && ptr.GetSize() < mbfc.maxMemoryPerObject {
9393
err = mbfc.mc.Put(address, ptr)
9494
if err != nil {
9595
slog.Debug(fmt.Sprintf("error caching to memory: %s", err.Error()))

pkg/rscache/memory_backed_file_cache_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,27 @@ func (*FakeReadCloser) Close() error {
3030
return nil
3131
}
3232

33+
// FakeFileCache implements the FileCache interface for testing
34+
type FakeFileCache struct {
35+
GetResult *CacheReturn
36+
}
37+
38+
func (f *FakeFileCache) Get(ctx context.Context, resolver ResolverSpec) *CacheReturn {
39+
return f.GetResult
40+
}
41+
42+
func (f *FakeFileCache) Check(ctx context.Context, resolver ResolverSpec) (bool, error) {
43+
return false, nil
44+
}
45+
46+
func (f *FakeFileCache) Head(ctx context.Context, resolver ResolverSpec) (int64, time.Time, error) {
47+
return 0, time.Time{}, nil
48+
}
49+
50+
func (f *FakeFileCache) Uncache(ctx context.Context, resolver ResolverSpec) error {
51+
return nil
52+
}
53+
3354
func (s *MemoryBackedFileCacheSuite) SetUpSuite(c *check.C) {
3455
c.Assert(s.tempdirhelper.SetUp(), check.IsNil)
3556
}
@@ -69,6 +90,66 @@ func (s *MemoryBackedFileCacheSuite) TestGetInMemory(c *check.C) {
6990
c.Check(obj.(*testItem), check.DeepEquals, &testItem{"one"})
7091
}
7192

93+
func (s *MemoryBackedFileCacheSuite) TestGetDoesNotCacheErrors(c *check.C) {
94+
defer leaktest.Check(c)
95+
96+
m := NewFakeMemoryCache(true)
97+
fc := &FakeFileCache{
98+
GetResult: &CacheReturn{
99+
Err: errors.New("some cache error"),
100+
CacheKey: "error-key",
101+
Size: 10,
102+
},
103+
}
104+
st := NewMemoryBackedFileCache(memCfg(fc, m, 10000000))
105+
106+
spec := ResolverSpec{
107+
CacheInMemory: true,
108+
Work: &FakeWork{
109+
address: "error-key",
110+
},
111+
}
112+
113+
// Call Get which should return the error
114+
result := st.Get(context.Background(), spec)
115+
c.Assert(result.Err, check.ErrorMatches, "some cache error")
116+
117+
// Verify the error result was NOT cached in memory
118+
cached := m.Get("error-key")
119+
c.Check(cached.IsNull(), check.Equals, true)
120+
}
121+
122+
func (s *MemoryBackedFileCacheSuite) TestGetCachesSuccessfulResults(c *check.C) {
123+
defer leaktest.Check(c)
124+
125+
m := NewFakeMemoryCache(true)
126+
fc := &FakeFileCache{
127+
GetResult: &CacheReturn{
128+
Value: []byte("success data"),
129+
CacheKey: "success-key",
130+
Size: 10,
131+
Complete: true,
132+
},
133+
}
134+
st := NewMemoryBackedFileCache(memCfg(fc, m, 10000000))
135+
136+
spec := ResolverSpec{
137+
CacheInMemory: true,
138+
Work: &FakeWork{
139+
address: "success-key",
140+
},
141+
}
142+
143+
// Call Get which should return successful result
144+
result := st.Get(context.Background(), spec)
145+
c.Assert(result.Err, check.IsNil)
146+
147+
// Verify the successful result WAS cached in memory
148+
cached := m.Get("success-key")
149+
c.Check(cached.IsNull(), check.Equals, false)
150+
c.Check(cached.ReturnedFrom, check.Equals, "memory")
151+
}
152+
72153
func (s *MemoryBackedFileCacheSuite) TestGetNotInMemoryErrs(c *check.C) {
73154
defer leaktest.Check(c)
74155

0 commit comments

Comments
 (0)