fix: pluginMap uses sync.Map to avoid data race

This commit is contained in:
徐聪
2022-08-01 17:04:39 +08:00
parent 44e844829d
commit c5a0a0fc27
4 changed files with 19 additions and 14 deletions
+8 -6
View File
@@ -101,11 +101,12 @@ func (b *HRPBoomer) Run(testcases ...ITestCase) {
// quit all plugins // quit all plugins
defer func() { defer func() {
if len(pluginMap) > 0 { pluginMap.Range(func(key, value interface{}) bool {
for _, plugin := range pluginMap { if plugin, ok := value.(funplugin.IPlugin); ok {
plugin.Quit() plugin.Quit()
} }
} return true
})
}() }()
taskSlice := b.ConvertTestCasesToBoomerTasks(testcases...) taskSlice := b.ConvertTestCasesToBoomerTasks(testcases...)
@@ -283,11 +284,12 @@ func (b *HRPBoomer) PollTasks(ctx context.Context) {
func (b *HRPBoomer) PollTestCases(ctx context.Context) { func (b *HRPBoomer) PollTestCases(ctx context.Context) {
// quit all plugins // quit all plugins
defer func() { defer func() {
if len(pluginMap) > 0 { pluginMap.Range(func(key, value interface{}) bool {
for _, plugin := range pluginMap { if plugin, ok := value.(funplugin.IPlugin); ok {
plugin.Quit() plugin.Quit()
} }
} return true
})
}() }()
for { for {
+5 -4
View File
@@ -5,6 +5,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"sync"
"github.com/httprunner/funplugin" "github.com/httprunner/funplugin"
"github.com/httprunner/funplugin/fungo" "github.com/httprunner/funplugin/fungo"
@@ -24,7 +25,7 @@ const (
const projectInfoFile = "proj.json" // used for ensuring root project const projectInfoFile = "proj.json" // used for ensuring root project
var pluginMap = map[string]funplugin.IPlugin{} // used for reusing plugin instance var pluginMap = sync.Map{} // used for reusing plugin instance
func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err error) { func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err error) {
// plugin file not found // plugin file not found
@@ -37,8 +38,8 @@ func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err er
} }
// reuse plugin instance if it already initialized // reuse plugin instance if it already initialized
if p, ok := pluginMap[pluginPath]; ok { if p, ok := pluginMap.Load(pluginPath); ok {
return p, nil return p.(funplugin.IPlugin), nil
} }
pluginOptions := []funplugin.Option{funplugin.WithLogOn(logOn)} pluginOptions := []funplugin.Option{funplugin.WithLogOn(logOn)}
@@ -74,7 +75,7 @@ func initPlugin(path, venv string, logOn bool) (plugin funplugin.IPlugin, err er
} }
// add plugin instance to plugin map // add plugin instance to plugin map
pluginMap[pluginPath] = plugin pluginMap.Store(pluginPath, plugin)
// report event for initializing plugin // report event for initializing plugin
event := sdk.EventTracking{ event := sdk.EventTracking{
+5 -3
View File
@@ -17,6 +17,7 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"github.com/httprunner/funplugin"
"github.com/httprunner/httprunner/v4/hrp/internal/builtin" "github.com/httprunner/httprunner/v4/hrp/internal/builtin"
"github.com/httprunner/httprunner/v4/hrp/internal/sdk" "github.com/httprunner/httprunner/v4/hrp/internal/sdk"
) )
@@ -188,11 +189,12 @@ func (r *HRPRunner) Run(testcases ...ITestCase) error {
// quit all plugins // quit all plugins
defer func() { defer func() {
if len(pluginMap) > 0 { pluginMap.Range(func(key, value interface{}) bool {
for _, plugin := range pluginMap { if plugin, ok := value.(funplugin.IPlugin); ok {
plugin.Quit() plugin.Quit()
} }
} return true
})
}() }()
var runErr error var runErr error
+1 -1
View File
@@ -24,7 +24,7 @@ func removeHashicorpGoPlugin() {
log.Info().Msg("[teardown] remove hashicorp go plugin") log.Info().Msg("[teardown] remove hashicorp go plugin")
os.Remove(tmpl("debugtalk.bin")) os.Remove(tmpl("debugtalk.bin"))
pluginPath, _ := filepath.Abs(tmpl("debugtalk.bin")) pluginPath, _ := filepath.Abs(tmpl("debugtalk.bin"))
delete(pluginMap, pluginPath) pluginMap.Delete(pluginPath)
} }
func buildHashicorpPyPlugin() { func buildHashicorpPyPlugin() {