You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2021/06/22 07:38:06 UTC
[apisix-go-plugin-runner] branch master updated: feat: concurrent
safe way to RegisterPlugin (#10)
This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-go-plugin-runner.git
The following commit(s) were added to refs/heads/master by this push:
new 6e33fa6 feat: concurrent safe way to RegisterPlugin (#10)
6e33fa6 is described below
commit 6e33fa657de759343f0a257c8de74fe635bd7da5
Author: tyltr <31...@users.noreply.github.com>
AuthorDate: Tue Jun 22 15:37:59 2021 +0800
feat: concurrent safe way to RegisterPlugin (#10)
---
internal/plugin/plugin.go | 16 +++-
internal/plugin/plugin_test.go | 192 +++++++++++++++++++++++++++++++++++++++--
2 files changed, 197 insertions(+), 11 deletions(-)
diff --git a/internal/plugin/plugin.go b/internal/plugin/plugin.go
index 7fa6136..a33c61a 100644
--- a/internal/plugin/plugin.go
+++ b/internal/plugin/plugin.go
@@ -18,6 +18,7 @@ import (
"errors"
"fmt"
"net/http"
+ "sync"
hrc "github.com/api7/ext-plugin-proto/go/A6/HTTPReqCall"
flatbuffers "github.com/google/flatbuffers/go"
@@ -36,6 +37,11 @@ type pluginOpts struct {
Filter FilterFunc
}
+type pluginRegistries struct {
+ sync.Mutex
+ opts map[string]*pluginOpts
+}
+
type ErrPluginRegistered struct {
name string
}
@@ -45,7 +51,7 @@ func (err ErrPluginRegistered) Error() string {
}
var (
- pluginRegistry = map[string]*pluginOpts{}
+ pluginRegistry = pluginRegistries{opts: map[string]*pluginOpts{}}
ErrMissingName = errors.New("missing name")
ErrMissingParseConfMethod = errors.New("missing ParseConf method")
@@ -67,15 +73,17 @@ func RegisterPlugin(name string, pc ParseConfFunc, sv FilterFunc) error {
ParseConf: pc,
Filter: sv,
}
- if _, found := pluginRegistry[name]; found {
+ pluginRegistry.Lock()
+ defer pluginRegistry.Unlock()
+ if _, found := pluginRegistry.opts[name]; found {
return ErrPluginRegistered{name}
}
- pluginRegistry[name] = opt
+ pluginRegistry.opts[name] = opt
return nil
}
func findPlugin(name string) *pluginOpts {
- if opt, found := pluginRegistry[name]; found {
+ if opt, found := pluginRegistry.opts[name]; found {
return opt
}
return nil
diff --git a/internal/plugin/plugin_test.go b/internal/plugin/plugin_test.go
index 65c9f9c..ecaad30 100644
--- a/internal/plugin/plugin_test.go
+++ b/internal/plugin/plugin_test.go
@@ -20,12 +20,12 @@ import (
"testing"
"time"
+ inHTTP "github.com/apache/apisix-go-plugin-runner/internal/http"
+ pkgHTTP "github.com/apache/apisix-go-plugin-runner/pkg/http"
+
hrc "github.com/api7/ext-plugin-proto/go/A6/HTTPReqCall"
flatbuffers "github.com/google/flatbuffers/go"
"github.com/stretchr/testify/assert"
-
- inHTTP "github.com/apache/apisix-go-plugin-runner/internal/http"
- pkgHTTP "github.com/apache/apisix-go-plugin-runner/pkg/http"
)
var (
@@ -94,10 +94,188 @@ func TestHTTPReqCall_FailedToParseConf(t *testing.T) {
}
func TestRegisterPlugin(t *testing.T) {
- assert.Equal(t, ErrMissingParseConfMethod,
- RegisterPlugin("bad_conf", nil, emptyFilter))
- assert.Equal(t, ErrMissingFilterMethod,
- RegisterPlugin("bad_conf", emptyParseConf, nil))
+ type args struct {
+ name string
+ pc ParseConfFunc
+ sv FilterFunc
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr error
+ }{
+ {
+ name: "test_MissingParseConfMethod",
+ args: args{
+ name: "1",
+ pc: nil,
+ sv: emptyFilter,
+ },
+ wantErr: ErrMissingParseConfMethod,
+ },
+ {
+ name: "test_MissingFilterMethod",
+ args: args{
+ name: "1",
+ pc: emptyParseConf,
+ sv: nil,
+ },
+ wantErr: ErrMissingFilterMethod,
+ },
+ {
+ name: "test_MissingParseConfMethod&FilterMethod",
+ args: args{
+ name: "1",
+ pc: nil,
+ sv: nil,
+ },
+ wantErr: ErrMissingParseConfMethod,
+ },
+ {
+ name: "test_MissingName&ParseConfMethod",
+ args: args{
+ name: "",
+ pc: nil,
+ sv: emptyFilter,
+ },
+ wantErr: ErrMissingName,
+ },
+ {
+ name: "test_MissingName&FilterMethod",
+ args: args{
+ name: "",
+ pc: emptyParseConf,
+ sv: nil,
+ },
+ wantErr: ErrMissingName,
+ },
+ {
+ name: "test_MissingAll",
+ args: args{
+ name: "",
+ pc: nil,
+ sv: nil,
+ },
+ wantErr: ErrMissingName,
+ },
+ {
+ name: "test_plugin1",
+ args: args{
+ name: "plugin1",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: nil,
+ },
+ {
+ name: "test_plugin1_again",
+ args: args{
+ name: "plugin1",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"plugin1"},
+ },
+ {
+ name: "test_plugin2",
+ args: args{
+ name: "plugin2111%#@#",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: nil,
+ },
+ {
+ name: "test_plugin3",
+ args: args{
+ name: "plugin311*%#@#",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: nil,
+ },
+ {
+ name: "test_plugin3_again",
+ args: args{
+ name: "plugin311*%#@#",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"plugin311*%#@#"},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := RegisterPlugin(tt.args.name, tt.args.pc, tt.args.sv); !assert.Equal(t, tt.wantErr, err) {
+ t.Errorf("RegisterPlugin() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
+
+func TestRegisterPluginConcurrent(t *testing.T) {
+ RegisterPlugin("test_concurrent-1", emptyParseConf, emptyFilter)
+ RegisterPlugin("test_concurrent-2", emptyParseConf, emptyFilter)
+ type args struct {
+ name string
+ pc ParseConfFunc
+ sv FilterFunc
+ }
+ type test struct {
+ name string
+ args args
+ wantErr error
+ }
+ tests := []test{
+ {
+ name: "test_concurrent-1",
+ args: args{
+ name: "test_concurrent-1",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"test_concurrent-1"},
+ },
+ {
+ name: "test_concurrent-2#01",
+ args: args{
+ name: "test_concurrent-2",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"test_concurrent-2"},
+ },
+ {
+ name: "test_concurrent-2#02",
+ args: args{
+ name: "test_concurrent-2",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"test_concurrent-2"},
+ },
+ {
+ name: "test_concurrent-2#03",
+ args: args{
+ name: "test_concurrent-2",
+ pc: emptyParseConf,
+ sv: emptyFilter,
+ },
+ wantErr: ErrPluginRegistered{"test_concurrent-2"},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ for i := 0; i < 3; i++ {
+ go func(tt test) {
+ if err := RegisterPlugin(tt.args.name, tt.args.pc, tt.args.sv); !assert.Equal(t, tt.wantErr, err) {
+ t.Errorf("RegisterPlugin() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ }(tt)
+ }
+
+ })
+ }
}
func TestFilter(t *testing.T) {