Skip to content

Commit f67bf24

Browse files
committed
完善 report 机制
1 parent 8ebbcf3 commit f67bf24

10 files changed

Lines changed: 140 additions & 196 deletions

File tree

_examples/report.go

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,16 @@ func reportLoad(reporter *cachego.Reporter, key string, value interface{}, ttl t
4040
}
4141

4242
func main() {
43-
// Create a cache as usual.
44-
cache := cachego.NewCache(
45-
cachego.WithMaxEntries(3),
46-
cachego.WithGC(100*time.Millisecond),
47-
)
48-
49-
// Use Report function to wrap a cache with reporting logics.
5043
// We provide some reporting points for monitor cache.
5144
// ReportMissed reports the missed key getting from cache.
5245
// ReportHit reports the hit entry getting from cache.
5346
// ReportGC reports the status of cache gc.
5447
// ReportLoad reports the result of loading.
55-
cache, reporter := cachego.Report(
56-
cache,
48+
// Use NewCacheWithReport to create a cache with report.
49+
cache, reporter := cachego.NewCacheWithReport(
50+
cachego.WithMaxEntries(3),
51+
cachego.WithGC(100*time.Millisecond),
52+
5753
cachego.WithReportMissed(reportMissed),
5854
cachego.WithReportHit(reportHit),
5955
cachego.WithReportGC(reportGC),

cache.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,7 @@ func RunGCTask(cache Cache, duration time.Duration) (cancel func()) {
116116
return cancel
117117
}
118118

119-
// NewCache creates a cache with options.
120-
// By default, it will create a standard cache which uses one lock to solve data race.
121-
// It may cause a big performance problem in high concurrency.
122-
// You can use WithShardings to create a sharding cache which is good for concurrency.
123-
// Also, you can use options to specify the type of cache to others, such as lru.
124-
func NewCache(opts ...Option) (cache Cache) {
119+
func newCache(withReport bool, opts ...Option) (cache Cache, reporter *Reporter) {
125120
conf := newDefaultConfig()
126121
applyOptions(conf, opts)
127122

@@ -136,9 +131,33 @@ func NewCache(opts ...Option) (cache Cache) {
136131
cache = newCache(conf)
137132
}
138133

134+
if withReport {
135+
cache, reporter = report(conf, cache)
136+
}
137+
139138
if conf.gcDuration > 0 {
140139
RunGCTask(cache, conf.gcDuration)
141140
}
142141

142+
return cache, reporter
143+
}
144+
145+
// NewCache creates a cache with options.
146+
// By default, it will create a standard cache which uses one lock to solve data race.
147+
// It may cause a big performance problem in high concurrency.
148+
// You can use WithShardings to create a sharding cache which is good for concurrency.
149+
// Also, you can use options to specify the type of cache to others, such as lru.
150+
// Use NewCacheWithReporter to get a reporter for use if you want.
151+
func NewCache(opts ...Option) (cache Cache) {
152+
cache, _ = newCache(false, opts...)
143153
return cache
144154
}
155+
156+
// NewCacheWithReport creates a cache and a reporter with options.
157+
// By default, it will create a standard cache which uses one lock to solve data race.
158+
// It may cause a big performance problem in high concurrency.
159+
// You can use WithShardings to create a sharding cache which is good for concurrency.
160+
// Also, you can use options to specify the type of cache to others, such as lru.
161+
func NewCacheWithReport(opts ...Option) (cache Cache, reporter *Reporter) {
162+
return newCache(true, opts...)
163+
}

cache_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ func testCacheImplement(t *testing.T, cache Cache) {
246246
}
247247
}
248248

249-
// go test -v -cover=^TestNew$
250-
func TestNew(t *testing.T) {
249+
// go test -v -cover=^TestNewCache$
250+
func TestNewCache(t *testing.T) {
251251
cache := NewCache()
252252

253253
sc1, ok := cache.(*standardCache)
@@ -290,6 +290,24 @@ func TestNew(t *testing.T) {
290290
cache = NewCache(WithLRU(0))
291291
}
292292

293+
// go test -v -cover=^TestNewCacheWithReport$
294+
func TestNewCacheWithReport(t *testing.T) {
295+
cache, reporter := NewCacheWithReport()
296+
297+
sc1, ok := cache.(*reportableCache)
298+
if !ok {
299+
t.Errorf("cache.(*reportableCache) %T not ok", cache)
300+
}
301+
302+
if sc1 == nil {
303+
t.Error("sc1 == nil")
304+
}
305+
306+
if reporter == nil {
307+
t.Error("reporter == nil")
308+
}
309+
}
310+
293311
// go test -v -cover=^TestRunGCTask$
294312
func TestRunGCTask(t *testing.T) {
295313
cache := new(testCache)

config.go

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,6 @@ type config struct {
2727

2828
now func() int64
2929
hash func(key string) int
30-
}
31-
32-
func newDefaultConfig() *config {
33-
return &config{
34-
cacheType: standard,
35-
shardings: 0,
36-
singleflight: true,
37-
gcDuration: 0,
38-
maxScans: 10000,
39-
maxEntries: 0,
40-
now: now,
41-
hash: hash,
42-
}
43-
}
44-
45-
type reportConfig struct {
46-
now func() int64
4730

4831
recordMissed bool
4932
recordHit bool
@@ -56,16 +39,19 @@ type reportConfig struct {
5639
reportLoad func(reporter *Reporter, key string, value interface{}, ttl time.Duration, err error)
5740
}
5841

59-
func newDefaultReportConfig() *reportConfig {
60-
return &reportConfig{
42+
func newDefaultConfig() *config {
43+
return &config{
44+
cacheType: standard,
45+
shardings: 0,
46+
singleflight: true,
47+
gcDuration: 0,
48+
maxScans: 10000,
49+
maxEntries: 0,
6150
now: now,
51+
hash: hash,
6252
recordMissed: true,
6353
recordHit: true,
6454
recordGC: true,
6555
recordLoad: true,
66-
reportMissed: nil,
67-
reportHit: nil,
68-
reportGC: nil,
69-
reportLoad: nil,
7056
}
7157
}

config_test.go

Lines changed: 13 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,6 @@ func isConfigEquals(conf1 *config, conf2 *config) bool {
5252
return false
5353
}
5454

55-
return true
56-
}
57-
58-
func isReportConfigEquals(conf1 *reportConfig, conf2 *reportConfig) bool {
59-
if fmt.Sprintf("%p", conf1.now) != fmt.Sprintf("%p", conf2.now) {
60-
return false
61-
}
62-
6355
if conf1.recordMissed != conf2.recordMissed {
6456
return false
6557
}
@@ -72,6 +64,10 @@ func isReportConfigEquals(conf1 *reportConfig, conf2 *reportConfig) bool {
7264
return false
7365
}
7466

67+
if conf1.recordLoad != conf2.recordLoad {
68+
return false
69+
}
70+
7571
if fmt.Sprintf("%p", conf1.reportMissed) != fmt.Sprintf("%p", conf2.reportMissed) {
7672
return false
7773
}
@@ -99,6 +95,10 @@ func TestApplyOptions(t *testing.T) {
9995
gcDuration: 0,
10096
maxScans: 0,
10197
maxEntries: 0,
98+
recordMissed: false,
99+
recordHit: false,
100+
recordGC: false,
101+
recordLoad: false,
102102
}
103103

104104
expect := &config{
@@ -107,6 +107,10 @@ func TestApplyOptions(t *testing.T) {
107107
gcDuration: 2,
108108
maxScans: 3,
109109
maxEntries: 4,
110+
recordMissed: true,
111+
recordHit: true,
112+
recordGC: true,
113+
recordLoad: true,
110114
}
111115

112116
applyOptions(got, []Option{
@@ -115,45 +119,13 @@ func TestApplyOptions(t *testing.T) {
115119
WithGC(2),
116120
WithMaxScans(3),
117121
WithMaxEntries(4),
118-
})
119-
120-
if !isConfigEquals(got, expect) {
121-
t.Errorf("got %+v != expect %+v", got, expect)
122-
}
123-
}
124-
125-
// go test -v -cover -run=^TestApplyReportOptions$
126-
func TestApplyReportOptions(t *testing.T) {
127-
reportHit := func(reporter *Reporter, key string, value interface{}) {}
128-
129-
got := &reportConfig{
130-
now: nil,
131-
recordMissed: false,
132-
recordHit: false,
133-
recordGC: false,
134-
recordLoad: false,
135-
reportHit: nil,
136-
}
137-
138-
expect := &reportConfig{
139-
now: now,
140-
recordMissed: true,
141-
recordHit: true,
142-
recordGC: true,
143-
recordLoad: true,
144-
reportHit: reportHit,
145-
}
146-
147-
applyReportOptions(got, []ReportOption{
148-
WithReporterNow(now),
149122
WithRecordMissed(true),
150123
WithRecordHit(true),
151124
WithRecordGC(true),
152125
WithRecordLoad(true),
153-
WithReportHit(reportHit),
154126
})
155127

156-
if !isReportConfigEquals(got, expect) {
128+
if !isConfigEquals(got, expect) {
157129
t.Errorf("got %+v != expect %+v", got, expect)
158130
}
159131
}

doc.go

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -330,36 +330,32 @@ Package cachego provides an easy way to use foundation for your caching operatio
330330
331331
8. report:
332332
333-
func reportMissed(key string) {
334-
fmt.Printf("report: missed key %s\n", key)
333+
func reportMissed(reporter *cachego.Reporter, key string) {
334+
fmt.Printf("report: missed key %s, missed rate %.3f\n", key, reporter.MissedRate())
335335
}
336336
337-
func reportHit(key string, value interface{}) {
338-
fmt.Printf("report: hit key %s value %+v\n", key, value)
337+
func reportHit(reporter *cachego.Reporter, key string, value interface{}) {
338+
fmt.Printf("report: hit key %s value %+v, hit rate %.3f\n", key, value, reporter.HitRate())
339339
}
340340
341-
func reportGC(cost time.Duration, cleans int) {
342-
fmt.Printf("report: gc cost %s cleans %d\n", cost, cleans)
341+
func reportGC(reporter *cachego.Reporter, cost time.Duration, cleans int) {
342+
fmt.Printf("report: gc cost %s cleans %d, gc count %d, cache size %d\n", cost, cleans, reporter.CountGC(), reporter.CacheSize())
343343
}
344344
345-
func reportLoad(key string, value interface{}, ttl time.Duration, err error) {
346-
fmt.Printf("report: load key %s value %+v ttl %s, err %+v\n", key, value, ttl, err)
345+
func reportLoad(reporter *cachego.Reporter, key string, value interface{}, ttl time.Duration, err error) {
346+
fmt.Printf("report: load key %s value %+v ttl %s, err %+v, load count %d\n", key, value, ttl, err, reporter.CountLoad())
347347
}
348348
349-
// Create a cache as usual.
350-
cache := cachego.NewCache(
351-
cachego.WithMaxEntries(3),
352-
cachego.WithGC(100*time.Millisecond),
353-
)
354-
355-
// Use Report function to wrap a cache with reporting logics.
356349
// We provide some reporting points for monitor cache.
357350
// ReportMissed reports the missed key getting from cache.
358351
// ReportHit reports the hit entry getting from cache.
359352
// ReportGC reports the status of cache gc.
360353
// ReportLoad reports the result of loading.
361-
cache, reporter := cachego.Report(
362-
cache,
354+
// Use NewCacheWithReport to create a cache with report.
355+
cache, reporter := cachego.NewCacheWithReport(
356+
cachego.WithMaxEntries(3),
357+
cachego.WithGC(100*time.Millisecond),
358+
363359
cachego.WithReportMissed(reportMissed),
364360
cachego.WithReportHit(reportHit),
365361
cachego.WithReportGC(reportGC),
@@ -390,6 +386,7 @@ Package cachego provides an easy way to use foundation for your caching operatio
390386
fmt.Println("CountMissed:", reporter.CountMissed())
391387
fmt.Println("CountHit:", reporter.CountHit())
392388
fmt.Println("CountGC:", reporter.CountGC())
389+
fmt.Println("CountLoad:", reporter.CountLoad())
393390
fmt.Println("CacheSize:", reporter.CacheSize())
394391
fmt.Println("MissedRate:", reporter.MissedRate())
395392
fmt.Println("HitRate:", reporter.HitRate())
@@ -454,4 +451,4 @@ Package cachego provides an easy way to use foundation for your caching operatio
454451
package cachego // import "github.com/FishGoddess/cachego"
455452

456453
// Version is the version string representation of cachego.
457-
const Version = "v0.4.4-alpha"
454+
const Version = "v0.4.5-alpha"

0 commit comments

Comments
 (0)