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 2022/02/18 03:59:26 UTC

[apisix-go-plugin-runner] branch master updated: feature: try to introduce context to plugin runner (#63)

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 8fdac12  feature: try to introduce context to plugin runner (#63)
8fdac12 is described below

commit 8fdac12de1d573a5505ce1068eb5ec2943200441
Author: JasonZhu <75...@qq.com>
AuthorDate: Fri Feb 18 11:55:28 2022 +0800

    feature: try to introduce context to plugin runner (#63)
    
    Co-authored-by: jasonzhu <zh...@meituan.com>
---
 go.sum                        | 11 -----------
 internal/http/request.go      | 19 +++++++++++++++++++
 internal/http/request_test.go | 17 +++++++++++++++++
 internal/util/msg.go          |  1 -
 pkg/http/http.go              |  9 +++++++++
 5 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/go.sum b/go.sum
index f58ccbe..8d14512 100644
--- a/go.sum
+++ b/go.sum
@@ -20,12 +20,6 @@ github.com/ReneKroon/ttlcache/v2 v2.4.0/go.mod h1:zbo6Pv/28e21Z8CzzqgYRArQYGYtjO
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alvaroloes/enumer v1.1.2/go.mod h1:FxrjvuXoDAx9isTJrv4c+T410zFi0DtXIT0m65DJ+Wo=
-github.com/api7/ext-plugin-proto v0.1.4 h1:gxw+fmtM2UPsSku+mEOFNTQpAGEOKrkWZvQgIcglaG0=
-github.com/api7/ext-plugin-proto v0.1.4/go.mod h1:8dbdAgCESeqwZ0IXirbjLbshEntmdrAX3uet+LW3jVU=
-github.com/api7/ext-plugin-proto v0.2.0 h1:XYws0+h7xHlAjSJ7OwmGm51vZwqeEwzTQrgwU0rY0P0=
-github.com/api7/ext-plugin-proto v0.2.0/go.mod h1:8dbdAgCESeqwZ0IXirbjLbshEntmdrAX3uet+LW3jVU=
-github.com/api7/ext-plugin-proto v0.2.1 h1:NRz4CxPM10KPHAJSv+5jcOMjQBJN8mninu9V6O62Mxw=
-github.com/api7/ext-plugin-proto v0.2.1/go.mod h1:8dbdAgCESeqwZ0IXirbjLbshEntmdrAX3uet+LW3jVU=
 github.com/api7/ext-plugin-proto v0.3.0 h1:exofn/9DIPpqMAu033M7TBXsWr/O0LUcIKuLUCF58Xk=
 github.com/api7/ext-plugin-proto v0.3.0/go.mod h1:8dbdAgCESeqwZ0IXirbjLbshEntmdrAX3uet+LW3jVU=
 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -193,7 +187,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
-github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -213,14 +206,12 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
 go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
 go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
 go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
 go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
 go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
@@ -249,7 +240,6 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
 golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 h1:2M3HP5CCK1Si9FQhwnzYhXdG6DXeebvUHFpre8QvbyI=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
@@ -332,7 +322,6 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8=
 golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
diff --git a/internal/http/request.go b/internal/http/request.go
index 09ffff7..ce7de9f 100644
--- a/internal/http/request.go
+++ b/internal/http/request.go
@@ -18,12 +18,14 @@
 package http
 
 import (
+	"context"
 	"encoding/binary"
 	"net"
 	"net/http"
 	"net/url"
 	"reflect"
 	"sync"
+	"time"
 
 	"github.com/api7/ext-plugin-proto/go/A6"
 	ei "github.com/api7/ext-plugin-proto/go/A6/ExtraInfo"
@@ -52,6 +54,9 @@ type Request struct {
 	rawArgs url.Values
 
 	vars map[string][]byte
+
+	ctx    context.Context
+	cancel context.CancelFunc
 }
 
 func (r *Request) ConfToken() uint32 {
@@ -158,12 +163,14 @@ func (r *Request) Var(name string) ([]byte, error) {
 }
 
 func (r *Request) Reset() {
+	defer r.cancel()
 	r.path = nil
 	r.hdr = nil
 	r.args = nil
 
 	r.vars = nil
 	r.conn = nil
+	r.ctx = nil
 
 	// Keep the fields below
 	// r.extraInfoHeader = nil
@@ -279,6 +286,13 @@ func (r *Request) BindConn(c net.Conn) {
 	r.conn = c
 }
 
+func (r *Request) Context() context.Context {
+	if r.ctx != nil {
+		return r.ctx
+	}
+	return context.Background()
+}
+
 func (r *Request) askExtraInfo(builder *flatbuffers.Builder,
 	infoType ei.Info, info flatbuffers.UOffsetT) ([]byte, error) {
 
@@ -342,6 +356,11 @@ var reqPool = sync.Pool{
 func CreateRequest(buf []byte) *Request {
 	req := reqPool.Get().(*Request)
 	req.r = hrc.GetRootAsReq(buf, 0)
+	// because apisix has an implicit 60s timeout, so set the timeout to 56 seconds(smaller than 60s)
+	// so plugin writer can still break the execution with a custom response before the apisix implicit timeout.
+	ctx, cancel := context.WithTimeout(context.Background(), 56*time.Second)
+	req.ctx = ctx
+	req.cancel = cancel
 	return req
 }
 
diff --git a/internal/http/request_test.go b/internal/http/request_test.go
index 9d56ce8..d276b5b 100644
--- a/internal/http/request_test.go
+++ b/internal/http/request_test.go
@@ -19,10 +19,12 @@ package http
 
 import (
 	"encoding/binary"
+	"fmt"
 	"net"
 	"net/http"
 	"net/url"
 	"testing"
+	"time"
 
 	"github.com/api7/ext-plugin-proto/go/A6"
 	ei "github.com/api7/ext-plugin-proto/go/A6/ExtraInfo"
@@ -381,3 +383,18 @@ func TestVar_FailedToReadExtraInfoResp(t *testing.T) {
 	_, err := r.Var("request_time")
 	assert.Equal(t, common.ErrConnClosed, err)
 }
+
+func TestContext(t *testing.T) {
+	out := buildReq(reqOpt{})
+	now := time.Now()
+	timeout, _ := time.ParseDuration("56s")
+	deadline := now.Add(timeout)
+	r := CreateRequest(out)
+	timer, ok := r.Context().Deadline()
+
+	assert.True(t, ok)
+	assert.True(t, timer.After(deadline))
+	fmt.Println(ok, timer.After(deadline))
+	ReuseRequest(r)
+	assert.Equal(t, r.ctx, nil)
+}
diff --git a/internal/util/msg.go b/internal/util/msg.go
index fca84d0..3020eb9 100644
--- a/internal/util/msg.go
+++ b/internal/util/msg.go
@@ -61,7 +61,6 @@ func ReadErr(n int, err error, required int) bool {
 
 func WriteErr(n int, err error) {
 	if err != nil {
-		// TODO: solve "write: broken pipe" with context
 		log.Errorf("write: %s", err)
 	}
 }
diff --git a/pkg/http/http.go b/pkg/http/http.go
index 92239eb..4fed2f6 100644
--- a/pkg/http/http.go
+++ b/pkg/http/http.go
@@ -18,6 +18,7 @@
 package http
 
 import (
+	"context"
 	"net"
 	"net/http"
 	"net/url"
@@ -58,6 +59,14 @@ type Request interface {
 	// the runner will ask it from the APISIX. If the RPC call is failed, an error in
 	// pkg/common.ErrConnClosed type is returned.
 	Var(name string) ([]byte, error)
+
+	// Context returns the request's context.
+	//
+	// The returned context is always non-nil; it defaults to the
+	// background context.
+	//
+	// For run plugin, the context controls cancellation.
+	Context() context.Context
 }
 
 // Header is like http.Header, but only implements the subset of its methods