Fixed data race issue while creating cache
diff --git a/common_helper.go b/common_helper.go
index d4e26d5..31f7d82 100644
--- a/common_helper.go
+++ b/common_helper.go
@@ -20,6 +20,9 @@
// Load data scope information into an in-memory cache so that for each record a DB lookup is not required
func createTenantCache() error {
+ // Lock before writing to the map as it has multiple readers
+ tenantCachelock.Lock()
+ defer tenantCachelock.Unlock()
tenantCache = make(map[string]tenant)
var org, env, tenantId, id string
@@ -30,9 +33,6 @@
return fmt.Errorf("Count not get datascope from DB due to: %v", error)
} else {
defer rows.Close()
- // Lock before writing to the map as it has multiple readers
- tenantCachelock.Lock()
- defer tenantCachelock.Unlock()
for rows.Next() {
rows.Scan(&env, &org, &tenantId, &id)
tenantCache[id] = tenant{Org: org, Env: env, TenantId: tenantId}
@@ -45,6 +45,9 @@
// Load data scope information into an in-memory cache so that for each record a DB lookup is not required
func createDeveloperInfoCache() error {
+ // Lock before writing to the map as it has multiple readers
+ developerInfoCacheLock.Lock()
+ defer developerInfoCacheLock.Unlock()
developerInfoCache = make(map[string]developerInfo)
var apiProduct, developerApp, developerEmail, developer sql.NullString
var tenantId, apiKey string
@@ -61,9 +64,6 @@
return fmt.Errorf("Count not get developerInfo from DB due to: %v", error)
} else {
defer rows.Close()
- // Lock before writing to the map as it has multiple readers
- developerInfoCacheLock.Lock()
- defer developerInfoCacheLock.Unlock()
for rows.Next() {
rows.Scan(&tenantId, &apiKey, &apiProduct, &developerApp, &developer, &developerEmail)
@@ -84,7 +84,10 @@
// Returns Tenant Info given a scope uuid from the cache or by querying the DB directly based on useCachig config
func getTenantForScope(scopeuuid string) (tenant, dbError) {
if config.GetBool(useCaching) {
- _, exists := tenantCache[scopeuuid]
+ // acquire a read lock as this cache has 1 writer as well
+ tenantCachelock.RLock()
+ defer tenantCachelock.RUnlock()
+ ten, exists := tenantCache[scopeuuid]
if !exists {
reason := "No tenant found for this scopeuuid: " + scopeuuid
errorCode := "UNKNOWN_SCOPE"
@@ -92,10 +95,7 @@
go createTenantCache()
return tenant{}, dbError{ErrorCode: errorCode, Reason: reason}
} else {
- // acquire a read lock as this cache has 1 writer as well
- tenantCachelock.RLock()
- defer tenantCachelock.RUnlock()
- return tenantCache[scopeuuid], dbError{}
+ return ten, dbError{}
}
} else {
var org, env, tenantId string
@@ -121,17 +121,17 @@
func getDeveloperInfo(tenantId string, apiKey string) developerInfo {
if config.GetBool(useCaching) {
keyForMap := getKeyForDeveloperInfoCache(tenantId, apiKey)
- _, exists := developerInfoCache[keyForMap]
+ // acquire a read lock as this cache has 1 writer as well
+ tenantCachelock.RLock()
+ defer tenantCachelock.RUnlock()
+ devInfo, exists := developerInfoCache[keyForMap]
if !exists {
log.Warnf("No data found for for tenantId = %s and apiKey = %s", tenantId, apiKey)
// Incase of unknown apiKey~tenantId, try to refresh the cache ansynchronously incase an update was missed or delayed
go createTenantCache()
return developerInfo{}
} else {
- // acquire a read lock as this cache has 1 writer as well
- developerInfoCacheLock.RLock()
- defer developerInfoCacheLock.RUnlock()
- return developerInfoCache[keyForMap]
+ return devInfo
}
} else {
var apiProduct, developerApp, developerEmail, developer sql.NullString