mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 11:18:50 +08:00
add MiddlewareNeverDoneCtx
for package ghttp
(#3250)
This commit is contained in:
parent
5a01798481
commit
4f4d2c2f8e
13
net/ghttp/ghttp_middleware_never_done_ctx.go
Normal file
13
net/ghttp/ghttp_middleware_never_done_ctx.go
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
package ghttp
|
||||
|
||||
// MiddlewareNeverDoneCtx sets the context never done for current process.
|
||||
func MiddlewareNeverDoneCtx(r *Request) {
|
||||
r.SetCtx(r.GetNeverDoneCtx())
|
||||
r.Middleware.Next()
|
||||
}
|
@ -13,6 +13,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
@ -345,3 +346,92 @@ func Test_Request_Form(t *testing.T) {
|
||||
}), "john")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Request_NeverDoneCtx_Done(t *testing.T) {
|
||||
var array = garray.New(true)
|
||||
s := g.Server(guid.S())
|
||||
s.BindHandler("/done", func(r *ghttp.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
ticker = time.NewTimer(time.Millisecond * 1500)
|
||||
)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
array.Append(1)
|
||||
return
|
||||
case <-ticker.C:
|
||||
array.Append(1)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
c := g.Client()
|
||||
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||
go func() {
|
||||
result := c.GetContent(ctx, "/done")
|
||||
fmt.Println(result)
|
||||
}()
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
t.Assert(array.Len(), 0)
|
||||
cancel()
|
||||
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
t.Assert(array.Len(), 1)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Request_NeverDoneCtx_NeverDone(t *testing.T) {
|
||||
var array = garray.New(true)
|
||||
s := g.Server(guid.S())
|
||||
s.Use(ghttp.MiddlewareNeverDoneCtx)
|
||||
s.BindHandler("/never-done", func(r *ghttp.Request) {
|
||||
var (
|
||||
ctx = r.Context()
|
||||
ticker = time.NewTimer(time.Millisecond * 1500)
|
||||
)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
array.Append(1)
|
||||
return
|
||||
case <-ticker.C:
|
||||
array.Append(1)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
s.SetDumpRouterMap(false)
|
||||
s.Start()
|
||||
defer s.Shutdown()
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
c := g.Client()
|
||||
c.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort()))
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||
go func() {
|
||||
result := c.GetContent(ctx, "/never-done")
|
||||
fmt.Println(result)
|
||||
}()
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
t.Assert(array.Len(), 0)
|
||||
cancel()
|
||||
|
||||
time.Sleep(time.Millisecond * 1500)
|
||||
t.Assert(array.Len(), 1)
|
||||
})
|
||||
}
|
||||
|
@ -32,7 +32,11 @@ func (c *neverDoneCtx) Err() error {
|
||||
}
|
||||
|
||||
// NeverDone wraps and returns a new context object that will be never done,
|
||||
// which forbids the context manually done, to make the context can be propagated to asynchronous goroutines.
|
||||
// which forbids the context manually done, to make the context can be propagated
|
||||
// to asynchronous goroutines.
|
||||
//
|
||||
// Note that, it does not affect the closing (canceling) of the parent context,
|
||||
// as it is a wrapper for its parent, which only affects the next context handling.
|
||||
func NeverDone(ctx context.Context) context.Context {
|
||||
return &neverDoneCtx{ctx}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user