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)
