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 <[email protected]>
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)

Reply via email to