This is an automated email from the ASF dual-hosted git repository.
lynwee pushed a commit to branch release-v1.0
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/release-v1.0 by this push:
new 540b0e361 fix(helpers): fix concurrent map writes (#7869) (#7870)
540b0e361 is described below
commit 540b0e361e9f2a50410b6e58800c4a9e950d99d7
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Aug 9 11:30:12 2024 +0800
fix(helpers): fix concurrent map writes (#7869) (#7870)
Co-authored-by: Lynwee <[email protected]>
---
.../pluginhelper/api/ds_remote_api_proxy_api.go | 26 +++++++++++++++-------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/backend/helpers/pluginhelper/api/ds_remote_api_proxy_api.go
b/backend/helpers/pluginhelper/api/ds_remote_api_proxy_api.go
index a0ec27f39..9ea8b5d2a 100644
--- a/backend/helpers/pluginhelper/api/ds_remote_api_proxy_api.go
+++ b/backend/helpers/pluginhelper/api/ds_remote_api_proxy_api.go
@@ -23,6 +23,7 @@ import (
"io"
"net/http"
"strings"
+ "sync"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/log"
@@ -32,8 +33,9 @@ import (
// DsRemoteApiProxyHelper is a helper to proxy api request to remote servers
type DsRemoteApiProxyHelper[C plugin.ToolLayerApiConnection] struct {
*ModelApiHelper[C]
- logger log.Logger
- httpClientCache map[string]*ApiClient
+ logger log.Logger
+ httpClientCache map[string]*ApiClient
+ httpClientCacheMutex *sync.RWMutex
}
// NewDsRemoteApiProxyHelper creates a new DsRemoteApiProxyHelper
@@ -43,9 +45,10 @@ func NewDsRemoteApiProxyHelper[
modelApiHelper *ModelApiHelper[C],
) *DsRemoteApiProxyHelper[C] {
return &DsRemoteApiProxyHelper[C]{
- ModelApiHelper: modelApiHelper,
- logger:
modelApiHelper.basicRes.GetLogger().Nested("remote_api_helper"),
- httpClientCache: make(map[string]*ApiClient),
+ ModelApiHelper: modelApiHelper,
+ logger:
modelApiHelper.basicRes.GetLogger().Nested("remote_api_helper"),
+ httpClientCache: make(map[string]*ApiClient),
+ httpClientCacheMutex: &sync.RWMutex{},
}
}
@@ -68,9 +71,14 @@ func (rap *DsRemoteApiProxyHelper[C])
getApiClient(connection *C) (*ApiClient, e
key = cacheableConn.GetHash()
}
// try to reuse api client
- if key != "" && rap.httpClientCache[key] != nil {
- rap.logger.Info("Reused api client")
- return rap.httpClientCache[key], nil
+ if key != "" {
+ rap.httpClientCacheMutex.RLock()
+ client, ok := rap.httpClientCache[key]
+ rap.httpClientCacheMutex.RUnlock()
+ if ok {
+ rap.logger.Info("Reused api client")
+ return client, nil
+ }
}
// create new client if cache missed
client, err := NewApiClientFromConnection(gocontext.TODO(),
rap.basicRes, c.(plugin.ApiConnection))
@@ -79,7 +87,9 @@ func (rap *DsRemoteApiProxyHelper[C]) getApiClient(connection
*C) (*ApiClient, e
}
// cache the client if key is not empty
if key != "" {
+ rap.httpClientCacheMutex.Lock()
rap.httpClientCache[key] = client
+ rap.httpClientCacheMutex.Unlock()
} else {
rap.logger.Info("No api client reuse")
}