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")
        }

Reply via email to