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/05/31 02:07:12 UTC

[apisix-go-plugin-runner] 05/22: feat: report error

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

commit 7e9d6ab70e2ad74269672b2987d9aa5d662e6a30
Author: spacewander <sp...@gmail.com>
AuthorDate: Wed May 19 14:56:12 2021 +0800

    feat: report error
---
 internal/plugin/conf.go       | 17 +++++++++--------
 internal/plugin/conf_test.go  |  6 +++---
 internal/server/error.go      | 44 +++++++++++++++++++++++++++++++++++++++++++
 internal/server/error_test.go | 40 +++++++++++++++++++++++++++++++++++++++
 internal/server/server.go     |  7 ++++++-
 5 files changed, 102 insertions(+), 12 deletions(-)

diff --git a/internal/plugin/conf.go b/internal/plugin/conf.go
index a6eccab..ae7d0c6 100644
--- a/internal/plugin/conf.go
+++ b/internal/plugin/conf.go
@@ -31,16 +31,12 @@ type ConfEntry struct {
 type RuleConf []ConfEntry
 
 var (
-	builder *flatbuffers.Builder
+	builder = flatbuffers.NewBuilder(1024)
 
 	cache        *ttlcache.Cache
 	cacheCounter uint32 = 0
 )
 
-func init() {
-	builder = flatbuffers.NewBuilder(1024)
-}
-
 func InitCache(ttl time.Duration) {
 	cache = ttlcache.NewCache()
 	cache.SetTTL(ttl)
@@ -56,7 +52,9 @@ func genCacheToken() uint32 {
 	return cacheCounter
 }
 
-func PrepareConf(buf []byte) []byte {
+func PrepareConf(buf []byte) ([]byte, error) {
+	builder.Reset()
+
 	req := pc.GetRootAsReq(buf, 0)
 	entries := make(RuleConf, req.ConfLength())
 
@@ -69,13 +67,16 @@ func PrepareConf(buf []byte) []byte {
 	}
 
 	token := genCacheToken()
-	cache.Set(strconv.FormatInt(int64(token), 10), entries)
+	err := cache.Set(strconv.FormatInt(int64(token), 10), entries)
+	if err != nil {
+		return nil, err
+	}
 
 	pc.RespStart(builder)
 	pc.RespAddConfToken(builder, token)
 	root := pc.RespEnd(builder)
 	builder.Finish(root)
-	return builder.FinishedBytes()
+	return builder.FinishedBytes(), nil
 }
 
 func GetRuleConf(token uint32) (RuleConf, error) {
diff --git a/internal/plugin/conf_test.go b/internal/plugin/conf_test.go
index cdb3749..1b2e668 100644
--- a/internal/plugin/conf_test.go
+++ b/internal/plugin/conf_test.go
@@ -34,11 +34,11 @@ func TestPrepareConf(t *testing.T) {
 	builder.Finish(root)
 	b := builder.FinishedBytes()
 
-	out := PrepareConf(b)
+	out, _ := PrepareConf(b)
 	resp := pc.GetRootAsResp(out, 0)
 	assert.Equal(t, uint32(1), resp.ConfToken())
 
-	out = PrepareConf(b)
+	out, _ = PrepareConf(b)
 	resp = pc.GetRootAsResp(out, 0)
 	assert.Equal(t, uint32(2), resp.ConfToken())
 }
@@ -51,7 +51,7 @@ func TestGetRuleConf(t *testing.T) {
 	builder.Finish(root)
 	b := builder.FinishedBytes()
 
-	out := PrepareConf(b)
+	out, _ := PrepareConf(b)
 	resp := pc.GetRootAsResp(out, 0)
 	assert.Equal(t, uint32(3), resp.ConfToken())
 
diff --git a/internal/server/error.go b/internal/server/error.go
new file mode 100644
index 0000000..8ba517c
--- /dev/null
+++ b/internal/server/error.go
@@ -0,0 +1,44 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package server
+
+import (
+	"github.com/ReneKroon/ttlcache/v2"
+	A6Err "github.com/api7/ext-plugin-proto/go/A6/Err"
+	flatbuffers "github.com/google/flatbuffers/go"
+)
+
+var (
+	builder = flatbuffers.NewBuilder(256)
+)
+
+func ReportError(err error) []byte {
+	builder.Reset()
+
+	A6Err.RespStart(builder)
+
+	var code A6Err.Code
+	switch err {
+	case ttlcache.ErrNotFound:
+		code = A6Err.CodeCONF_TOKEN_NOT_FOUND
+	default:
+		code = A6Err.CodeSERVICE_UNAVAILABLE
+	}
+
+	A6Err.RespAddCode(builder, code)
+	resp := A6Err.RespEnd(builder)
+	builder.Finish(resp)
+	return builder.FinishedBytes()
+}
diff --git a/internal/server/error_test.go b/internal/server/error_test.go
new file mode 100644
index 0000000..9586ba5
--- /dev/null
+++ b/internal/server/error_test.go
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package server
+
+import (
+	"io"
+	"testing"
+	"time"
+
+	"github.com/apache/apisix-go-plugin-runner/internal/plugin"
+	A6Err "github.com/api7/ext-plugin-proto/go/A6/Err"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestReportErrorCacheToken(t *testing.T) {
+	plugin.InitCache(10 * time.Millisecond)
+
+	_, err := plugin.GetRuleConf(uint32(999999))
+	b := ReportError(err)
+	resp := A6Err.GetRootAsResp(b, 0)
+	assert.Equal(t, A6Err.CodeCONF_TOKEN_NOT_FOUND, resp.Code())
+}
+
+func TestReportErrorUnknownErr(t *testing.T) {
+	b := ReportError(io.EOF)
+	resp := A6Err.GetRootAsResp(b, 0)
+	assert.Equal(t, A6Err.CodeSERVICE_UNAVAILABLE, resp.Code())
+}
diff --git a/internal/server/server.go b/internal/server/server.go
index 0180ed6..8f333fb 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -90,7 +90,12 @@ func handleConn(c net.Conn) {
 		var out []byte
 		switch ty {
 		case RPCPrepareConf:
-			out = plugin.PrepareConf(buf)
+			out, err = plugin.PrepareConf(buf)
+		}
+
+		if err != nil {
+			ty = RPCError
+			out = ReportError(err)
 		}
 
 		size := len(out)