Last active
December 31, 2015 19:43
-
-
Save micahhausler/2b1f2b939666ed3266c5 to your computer and use it in GitHub Desktop.
Go map Data Race
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cache | |
import ( | |
"sync" | |
) | |
// UserCache stores a concurrent-safe cache of authenticated users | |
type UserCache struct { | |
mu sync.RWMutex // guards Cache | |
Cache map[string]string | |
} | |
// Get gets a value from the cache, concurrent-safe | |
func (cache *UserCache) Get(key string) (string, bool) { | |
cache.mu.RLock() | |
defer cache.mu.RUnlock() | |
value, ok := cache.Cache[key] | |
return value, ok | |
} | |
// Set a key/value in the cache, concurrent-safe | |
func (cache *UserCache) Set(key, value string) { | |
cache.mu.Lock() | |
cache.Cache[key] = value | |
cache.mu.Unlock() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cache | |
import ( | |
"testing" | |
"time" | |
) | |
func TestUserCacheSet(t *testing.T) { | |
cache := UserCache{Cache: make(map[string]string)} | |
var tests = []struct { | |
key, value string | |
}{ | |
{"a", "A"}, | |
{"b", "B"}, | |
{"c", "C"}, | |
} | |
// set values | |
for _, test := range tests { | |
// incorrect! | |
/* | |
go func() { | |
cache.Set(test.key, test.value) | |
}() | |
*/ | |
// corrected | |
go func(k, v string) { | |
cache.Set(k, v) | |
}(test.key, test.value) | |
} | |
time.Sleep(time.Second) | |
for _, test := range tests { | |
got, ok := cache.Get(test.key) | |
if !ok { | |
t.Errorf( | |
"cache.Get(\"%s\") returned not ok, should have been ok", | |
test.key, | |
) | |
} | |
if got != test.value && ok { | |
t.Errorf( | |
"cache.Get(\"%s\") returned \"%s\", wanted \"%s\"", | |
test.key, got, test.value, | |
) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ go test -race . | |
================== | |
WARNING: DATA RACE | |
Read by goroutine 7: | |
github.com/micahhausler/cache.TestUserCacheSet.func1() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:22 +0x2e | |
Previous write by goroutine 6: | |
github.com/micahhausler/cache.TestUserCacheSet() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:20 +0x2a6 | |
testing.tRunner() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:456 +0xdc | |
Goroutine 7 (running) created at: | |
github.com/micahhausler/cache.TestUserCacheSet() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:23 +0x2f9 | |
testing.tRunner() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:456 +0xdc | |
Goroutine 6 (running) created at: | |
testing.RunTests() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:561 +0xaa3 | |
testing.(*M).Run() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:494 +0xe4 | |
main.main() | |
github.com/micahhausler/cache/_test/_testmain.go:54 +0x20f | |
================== | |
================== | |
WARNING: DATA RACE | |
Read by goroutine 7: | |
github.com/micahhausler/cache.TestUserCacheSet.func1() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:22 +0x41 | |
Previous write by goroutine 6: | |
github.com/micahhausler/cache.TestUserCacheSet() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:20 +0x2a6 | |
testing.tRunner() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:456 +0xdc | |
Goroutine 7 (running) created at: | |
github.com/micahhausler/cache.TestUserCacheSet() | |
/Users/micahhausler/code/go/src/github.com/micahhausler/cache/cache_test.go:23 +0x2f9 | |
testing.tRunner() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:456 +0xdc | |
Goroutine 6 (running) created at: | |
testing.RunTests() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:561 +0xaa3 | |
testing.(*M).Run() | |
/usr/local/Cellar/go/1.5.2/libexec/src/testing/testing.go:494 +0xe4 | |
main.main() | |
github.com/micahhausler/cache/_test/_testmain.go:54 +0x20f | |
================== | |
--- FAIL: TestUserCacheSet (1.00s) | |
cache_test.go:33: cache.Get("a") returned not ok, should have been ok | |
cache_test.go:33: cache.Get("b") returned not ok, should have been ok | |
FAIL | |
FAIL github.com/micahhausler/cache 1.016s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment