diff --git a/g/net/ghttp/ghttp_client_request.go b/g/net/ghttp/ghttp_client_request.go index a1330b9a8..ffd6b16f1 100644 --- a/g/net/ghttp/ghttp_client_request.go +++ b/g/net/ghttp/ghttp_client_request.go @@ -3,6 +3,7 @@ // 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://gitee.com/johng/gf. + // HTTP客户端请求. package ghttp @@ -40,7 +41,7 @@ func NewClient() (*Client) { } } -// 设置HTTP Headerss +// 设置HTTP Header func (c *Client) SetHeader(key, value string) { c.header[key] = value } @@ -223,3 +224,58 @@ func Trace(url, data string) (*ClientResponse, error) { func DoRequest(method, url string, data []byte) (*ClientResponse, error) { return NewClient().DoRequest(method, url, data) } + +// GET请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针) +func GetContent(url string, data...string) string { + return RequestContent("GET", url, data...) +} + +// PUT请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针) +func PutContent(url string, data...string) string { + return RequestContent("PUT", url, data...) +} + +// POST请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针) +func PostContent(url string, data...string) string { + return RequestContent("POST", url, data...) +} + +// DELETE请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针) +func DeleteContent(url string, data...string) string { + return RequestContent("DELETE", url, data...) +} + +func HeadContent(url string, data...string) string { + return RequestContent("HEAD", url, data...) +} + +func PatchContent(url string, data...string) string { + return RequestContent("PATCH", url, data...) +} + +func ConnectContent(url string, data...string) string { + return RequestContent("CONNECT", url, data...) +} + +func OptionsContent(url string, data...string) string { + return RequestContent("OPTIONS", url, data...) +} + +func TraceContent(url string, data...string) string { + return RequestContent("TRACE", url, data...) +} + +// 请求并返回服务端结果(内部会自动读取服务端返回结果并关闭缓冲区指针) +func RequestContent(method string, url string, data...string) string { + content := "" + if len(data) > 0 { + content = data[0] + } + response, err := NewClient().DoRequest(method, url, []byte(content)) + if err != nil { + return "" + } + defer response.Close() + return string(response.ReadAll()) +} + diff --git a/g/net/ghttp/ghttp_unit_1_test.go b/g/net/ghttp/ghttp_unit_1_test.go new file mode 100644 index 000000000..0facf0d6c --- /dev/null +++ b/g/net/ghttp/ghttp_unit_1_test.go @@ -0,0 +1,49 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + + +package ghttp_test + +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/net/ghttp" + "gitee.com/johng/gf/g/os/gtime" + "gitee.com/johng/gf/g/util/gtest" + "testing" + "time" +) + +// 基本路由功能以及优先级测试 +func Test_Router_Basic(t *testing.T) { + s := g.Server(gtime.Nanosecond()) + s.BindHandler("/:name", func(r *ghttp.Request){ + r.Response.Write("/:name") + }) + s.BindHandler("/:name/update", func(r *ghttp.Request){ + r.Response.Write(r.Get("name")) + }) + s.BindHandler("/:name/:action", func(r *ghttp.Request){ + r.Response.Write(r.Get("action")) + }) + s.BindHandler("/:name/*any", func(r *ghttp.Request){ + r.Response.Write(r.Get("any")) + }) + s.BindHandler("/user/list/{field}.html", func(r *ghttp.Request){ + r.Response.Write(r.Get("field")) + }) + s.SetPort(8199) + s.SetDumpRouteMap(false) + go s.Run() + defer s.Shutdown() + // 等待启动完成 + time.Sleep(time.Second) + gtest.Case(func() { + gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john"), "") + gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john/update"), "john") + gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/john/edit"), "edit") + gtest.Assert(ghttp.GetContent("http://127.0.0.1:8199/user/list/100.html"), "100") + }) +} diff --git a/g/net/ghttp/ghttp_unit_2_test.go b/g/net/ghttp/ghttp_unit_2_test.go new file mode 100644 index 000000000..167d6a7ae --- /dev/null +++ b/g/net/ghttp/ghttp_unit_2_test.go @@ -0,0 +1,115 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). 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://gitee.com/johng/gf. + +// 分组路由测试 + +package ghttp_test + +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/frame/gmvc" + "gitee.com/johng/gf/g/net/ghttp" + "gitee.com/johng/gf/g/os/gtime" + "gitee.com/johng/gf/g/util/gtest" + "testing" + "time" +) + +// 执行对象 +type Object struct {} + +func (o *Object) Show(r *ghttp.Request) { + r.Response.Write("Object Show") +} + +func (o *Object) Delete(r *ghttp.Request) { + r.Response.Write("Object REST Delete") +} + +// 控制器 +type Controller struct { + gmvc.Controller +} + +func (c *Controller) Show() { + c.Response.Write("Controller Show") +} + +func (c *Controller) Post() { + c.Response.Write("Controller REST Post") +} + +func Handler(r *ghttp.Request) { + r.Response.Write("Handler") +} + +func Test_Router_Group1(t *testing.T) { + s := g.Server(gtime.Nanosecond()) + obj := new(Object) + ctl := new(Controller) + // 分组路由方法注册 + g := s.Group("/api") + g.ALL ("/handler", Handler) + g.ALL ("/ctl", ctl) + g.GET ("/ctl/my-show", ctl, "Show") + g.REST("/ctl/rest", ctl) + g.ALL ("/obj", obj) + g.GET ("/obj/my-show", obj, "Show") + g.REST("/obj/rest", obj) + s.SetPort(8199) + s.SetDumpRouteMap(false) + go s.Run() + defer s.Shutdown() + time.Sleep(time.Second) + gtest.Case(func() { + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/handler"), "Handler") + + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/my-show"), "Controller Show") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/post"), "Controller REST Post") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/show"), "Controller Show") + gtest.Assert(ghttp.PostContent("http://127.0.0.1:8199/api/ctl/rest"), "Controller REST Post") + + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/delete"), "Object REST Delete") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/my-show"), "Object Show") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/show"), "Object Show") + gtest.Assert(ghttp.DeleteContent("http://127.0.0.1:8199/api/obj/rest"), "Object REST Delete") + + }) +} + +func Test_Router_Group2(t *testing.T) { + s := g.Server(gtime.Nanosecond()) + obj := new(Object) + ctl := new(Controller) + // 分组路由批量注册 + s.Group("/api").Bind("/api", []ghttp.GroupItem{ + {"ALL", "/handler", Handler}, + {"ALL", "/ctl", ctl}, + {"GET", "/ctl/my-show", ctl, "Show"}, + {"REST", "/ctl/rest", ctl}, + {"ALL", "/obj", obj}, + {"GET", "/obj/my-show", obj, "Show"}, + {"REST", "/obj/rest", obj}, + }) + s.SetPort(8199) + s.SetDumpRouteMap(false) + go s.Run() + defer s.Shutdown() + time.Sleep(time.Second) + gtest.Case(func() { + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/handler"), "Handler") + + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/my-show"), "Controller Show") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/post"), "Controller REST Post") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/ctl/show"), "Controller Show") + gtest.Assert(ghttp.PostContent("http://127.0.0.1:8199/api/ctl/rest"), "Controller REST Post") + + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/delete"), "Object REST Delete") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/my-show"), "Object Show") + gtest.Assert(ghttp.GetContent ("http://127.0.0.1:8199/api/obj/show"), "Object Show") + gtest.Assert(ghttp.DeleteContent("http://127.0.0.1:8199/api/obj/rest"), "Object REST Delete") + }) +} diff --git a/g/os/gtimew/gtimew.go b/g/os/gtimew/gtimew.go index 6bb8f7f50..8cb147310 100644 --- a/g/os/gtimew/gtimew.go +++ b/g/os/gtimew/gtimew.go @@ -5,7 +5,7 @@ // You can obtain one at https://gitee.com/johng/gf. // Package gtimew provides Time Wheel for interval jobs running management/时间轮. -// 高效的时间轮任务执行管理,用于管理异步的间隔运行任务,或者异步延迟只运行一次的任务(最小时间粒度为秒)。 +// 高效的时间轮任务执行管理,用于管理异步的间隔运行任务,或者异步只运行一次的任务(最小时间粒度为秒)。 // 与其他定时任务管理模块的区别是,时间轮模块只管理间隔执行任务,并且更注重执行效率(纳秒级别)。 package gtimew @@ -61,6 +61,11 @@ func Entries() []*Entry { return defaultWheel.Entries() } +// 当前时间轮已注册的任务数 +func Size() int { + return defaultWheel.Size() +} + // 在Job方法中调用,停止当前运行的Job func ExitJob() { panic(gPANIC_EXIT) diff --git a/g/os/gtimew/gtimew_unit_1_test.go b/g/os/gtimew/gtimew_unit_1_test.go index b1a11ba0e..7b4afcf19 100644 --- a/g/os/gtimew/gtimew_unit_1_test.go +++ b/g/os/gtimew/gtimew_unit_1_test.go @@ -32,7 +32,7 @@ func TestWheel_Add_Close(t *testing.T) { gtest.AssertNE(entry1, nil) gtest.AssertNE(entry2, nil) gtest.AssertNE(entry3, nil) - gtest.Assert(len(wheel.Entries()), 3) + gtest.Assert(wheel.Size(), 3) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 2) time.Sleep(1100*time.Millisecond) @@ -54,7 +54,7 @@ func TestWheel_Singlton(t *testing.T) { time.Sleep(10*time.Second) }) gtest.AssertNE(entry, nil) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 1) @@ -91,9 +91,9 @@ func TestWheel_DelayAdd(t *testing.T) { gtest.Case(func() { wheel := gtimew.New() wheel.DelayAdd(1, 1, func() {}) - gtest.Assert(len(wheel.Entries()), 0) + gtest.Assert(wheel.Size(), 0) time.Sleep(1100*time.Millisecond) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) }) } @@ -105,9 +105,9 @@ func TestWheel_DelayAdd_Singleton(t *testing.T) { array.Append(1) time.Sleep(10*time.Second) }) - gtest.Assert(len(wheel.Entries()), 0) + gtest.Assert(wheel.Size(), 0) time.Sleep(1100*time.Millisecond) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) gtest.Assert(array.Len(), 0) time.Sleep(1100*time.Millisecond) @@ -122,9 +122,9 @@ func TestWheel_DelayAdd_Once(t *testing.T) { wheel.DelayAddOnce(1, 1, func() { array.Append(1) }) - gtest.Assert(len(wheel.Entries()), 0) + gtest.Assert(wheel.Size(), 0) time.Sleep(1100*time.Millisecond) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) gtest.Assert(array.Len(), 0) time.Sleep(1100*time.Millisecond) @@ -145,6 +145,6 @@ func TestWheel_ExitJob(t *testing.T) { }) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 1) - gtest.Assert(len(wheel.Entries()), 0) + gtest.Assert(wheel.Size(), 0) }) } diff --git a/g/os/gtimew/gtimew_unit_2_test.go b/g/os/gtimew/gtimew_unit_2_test.go index 0776043f9..99bf32dab 100644 --- a/g/os/gtimew/gtimew_unit_2_test.go +++ b/g/os/gtimew/gtimew_unit_2_test.go @@ -23,7 +23,7 @@ func TestWheel_Entry_Operation(t *testing.T) { array.Append(1) }) gtest.AssertNE(entry, nil) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 1) entry.Stop() @@ -44,7 +44,7 @@ func TestWheel_Entry_Singlton(t *testing.T) { entry.SetMode(gtimew.MODE_SINGLETON) gtest.AssertNE(entry, nil) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 1) @@ -61,8 +61,8 @@ func TestWheel_Entry_Once(t *testing.T) { entry.SetMode(gtimew.MODE_ONCE) gtest.AssertNE(entry, nil) - gtest.Assert(len(wheel.Entries()), 1) + gtest.Assert(wheel.Size(), 1) time.Sleep(1100*time.Millisecond) gtest.Assert(array.Len(), 1) - gtest.Assert(len(wheel.Entries()), 0) + gtest.Assert(wheel.Size(), 0) } diff --git a/g/os/gtimew/gtimew_wheel.go b/g/os/gtimew/gtimew_wheel.go index 818845899..62c55863c 100644 --- a/g/os/gtimew/gtimew_wheel.go +++ b/g/os/gtimew/gtimew_wheel.go @@ -75,6 +75,11 @@ func (w *Wheel) DelayAddOnce(delay int, interval int, job JobFunc) { }() } +// 当前时间轮已注册的任务数 +func (w *Wheel) Size() int { + return w.entries.Len() +} + // 关闭循环任务 func (w *Wheel) Close() { w.status.Set(STATUS_CLOSED)