Skip to content

Commit

Permalink
提供一种新的类全局timeout方法, 收敛包级别的超时设置 (#295)
Browse files Browse the repository at this point in the history
* 提供一种新的类全局timeout方法, 收敛包级别的超时设置

* 修改readme
  • Loading branch information
guonaihong authored Jul 5, 2021
1 parent 758557a commit 732cbb9
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 13 deletions.
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ gout 是go写的http 客户端,为提高工作效率而开发
* 支持设置 json 编码到请求 body 里面(可传struct, map, string, []byte 等类型)
* 支持设置 xml 编码到请求 body 里面(可传struct, string, []byte 等类型)
* 支持设置 yaml 编码到请求 body 里面(可传struct, map, string, []byte 等类型)
* 支持设置 protobuf 编码到请求 body里面(可传struct)
* 支持设置 form-data(可传 struct, map, array, slice 等类型)
* 支持设置 x-www-form-urlencoded(可传 struct,map,array,slice 等类型)
* 支持设置 io.Reader,uint/uint8/uint16...int/int8...string...[]byte...float32,float64 至请求 body 里面
Expand Down Expand Up @@ -88,9 +89,11 @@ gout 是go写的http 客户端,为提高工作效率而开发
- [generate curl command](#generate-curl-command)
- [Incoming custom * http.Client](#Incoming-custom-*http.Client)
- [Using chunked data format](#Using-chunked-data-format)
- [Global configuration](#Global-configuration)
- [NewWithOpt](#NewWithOpt)
- [Insecure skip verify](#insecure-skip-verify)
- [Turn off 3xx status code automatic jump](#Turn-off-3xx-status-code-automatic-jump)
- [NewWithOpt set timeout](#NewWithOpt-set-timeout)
- [Global configuration](#Global-configuration)
- [set timeout](#set-timeout)
- [Unique features](#Unique-features)
- [forward gin data](#forward-gin-data)
Expand Down Expand Up @@ -1635,7 +1638,7 @@ func main() {
// nc -l 8080
```

# Global configuration
# NewWithOpt
这里记录全局配置的方法, 后面所有的全局配置都推荐使用```gout.NewWithOpt```接口的实现
## insecure skip verify
忽略ssl验证, 使用```gout.WithInsecureSkipVerify()```接口配置该功能, 传入```gout.NewWithOpt```接口即可生效.
Expand Down Expand Up @@ -1671,9 +1674,25 @@ func main() {
}
}
```
## NewWithOpt set timeout
```gout.WithTimeout``` 为了让大家少用```gout.SetTimeout```而设计
```go
import (
"github.com/guonaihong/gout"
)
func main() {
// globalWithOpt里面包含连接池, 这是一个全局可复用的对象, 一个进程里面可能只需创建1个
globalWithOpt := gout.NewWithOpt(gout.WithTimeout())
err := globalWithOpt.GET("url").Do()
if err != nil {
fmt.Printf("err = %v\n" ,err)
return
}
}
```


# Global configuration
## set timeout

设置全局超时时间。可以简化一些代码。在使用全局配置默认你已经了解它会带来的一些弊端.
Expand Down
7 changes: 7 additions & 0 deletions dataflow/dataflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/guonaihong/gout/decode"
"github.com/guonaihong/gout/encode"
api "github.com/guonaihong/gout/interface"
"github.com/guonaihong/gout/setting"
"golang.org/x/net/proxy"
"net"
"net/http"
Expand Down Expand Up @@ -73,6 +74,12 @@ func (df *DataFlow) OPTIONS(url string) *DataFlow {
return df
}

// SetSetting
func (df *DataFlow) SetSetting(s setting.Setting) *DataFlow {
df.Req.Setting = s
return df
}

// SetHost set host
func (df *DataFlow) SetHost(host string) *DataFlow {
if df.Err != nil {
Expand Down
1 change: 1 addition & 0 deletions dataflow/gout.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func New(c ...*http.Client) *Gout {
return out
}

// TODO 这一层可以直接删除
// GET send HTTP GET method
func GET(url string) *DataFlow {
return New().GET(url)
Expand Down
10 changes: 9 additions & 1 deletion dataflow/req.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,5 +512,13 @@ func modifyURL(url string) string {
}

func reqDef(method string, url string, g *Gout) Req {
return Req{method: method, url: modifyURL(url), g: g, Setting: GlobalSetting}
r := Req{method: method, url: modifyURL(url), g: g}
//后面收敛GlobalSetting, 计划删除这个变量
//先这么写, 控制影响的范围
r.Setting.NotIgnoreEmpty = GlobalSetting.NotIgnoreEmpty
r.Setting.Timeout = GlobalSetting.Timeout
r.Setting.Index = GlobalSetting.Index
r.TimeoutIndex = GlobalSetting.TimeoutIndex

return r
}
18 changes: 11 additions & 7 deletions gout_newopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type Client struct {
options
}

// NewWithOpt 设计哲学
// 1.一些不经常变化的配置放到NewWithOpt里面实现
// 2.一些和http.Client深度绑定的放到NewWithOpt里面实现
// 3.一些可以提升使用体验的放到NewWithOpt里面实现
func NewWithOpt(opts ...Option) *Client {
c := &Client{}
c.hc = &http.Client{}
Expand All @@ -24,35 +28,35 @@ func NewWithOpt(opts ...Option) *Client {

// GET send HTTP GET method
func (c *Client) GET(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).GET(url)
return dataflow.New(c.hc).GET(url).SetSetting(c.Setting)
}

// POST send HTTP POST method
func (c *Client) POST(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).POST(url)
return dataflow.New(c.hc).POST(url).SetSetting(c.Setting)
}

// PUT send HTTP PUT method
func (c *Client) PUT(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).PUT(url)
return dataflow.New(c.hc).PUT(url).SetSetting(c.Setting)
}

// DELETE send HTTP DELETE method
func (c *Client) DELETE(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).DELETE(url)
return dataflow.New(c.hc).DELETE(url).SetSetting(c.Setting)
}

// PATCH send HTTP PATCH method
func (c *Client) PATCH(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).PATCH(url)
return dataflow.New(c.hc).PATCH(url).SetSetting(c.Setting)
}

// HEAD send HTTP HEAD method
func (c *Client) HEAD(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).HEAD(url)
return dataflow.New(c.hc).HEAD(url).SetSetting(c.Setting)
}

// OPTIONS send HTTP OPTIONS method
func (c *Client) OPTIONS(url string) *dataflow.DataFlow {
return dataflow.New(c.hc).OPTIONS(url)
return dataflow.New(c.hc).OPTIONS(url).SetSetting(c.Setting)
}
File renamed without changes.
35 changes: 34 additions & 1 deletion timeout_test.go → gout_newopt_timeout_and_global_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ func Test_Global_Timeout(t *testing.T) {
// 只设置timeout
SetTimeout(shortTimeout * time.Millisecond) //设置全局超时时间
err := GET(ts.URL + "/timeout").Do()
// 期望的结果是返回错误
assert.Error(t, err)

// 使用互斥api的原则,后面的覆盖前面的
// 这里是WithContext生效, 超时时间400ms
// 这里是WithContext生效, 预期超时时间400ms
ctx, _ := context.WithTimeout(context.Background(), longTimeout*time.Millisecond)
s := time.Now()
SetTimeout(shortTimeout * time.Millisecond) // 设置全局超时时间
Expand All @@ -59,3 +60,35 @@ func Test_Global_Timeout(t *testing.T) {

SetTimeout(time.Duration(0))
}

func Test_NewWithOpt_Timeout(t *testing.T) {
router := setupDataFlow(t)

const (
longTimeout = 400
middleTimeout = 300
shortTimeout = 200
)

ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
defer ts.Close()

// 只设置timeout
greq := NewWithOpt(WithTimeout(shortTimeout * time.Millisecond)) //设置全局超时时间
err := greq.GET(ts.URL + "/timeout").Do()
// 期望的结果是返回错误
assert.Error(t, err)

// 使用互斥api的原则,后面的覆盖前面的
// 这里是WithContext生效, 预期超时时间400ms
ctx, _ := context.WithTimeout(context.Background(), longTimeout*time.Millisecond)
s := time.Now()
greq = NewWithOpt(WithTimeout(shortTimeout * time.Millisecond)) // 设置全局超时时间
err = greq.GET(ts.URL + "/timeout").
WithContext(ctx).
Do()

assert.Error(t, err)
assert.GreaterOrEqual(t, int(time.Now().Sub(s)), int(middleTimeout*time.Millisecond))

}
15 changes: 15 additions & 0 deletions gout_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package gout
import (
"crypto/tls"
"net/http"
"time"

"github.com/guonaihong/gout/setting"
)

type options struct {
hc *http.Client
setting.Setting
}

type Option interface {
Expand Down Expand Up @@ -57,3 +61,14 @@ func (c close3xx) apply(opts *options) {
func WithClose3xxJump() Option {
return close3xx{}
}

// 4.timeout
type timeout time.Duration

func WithTimeout(t time.Duration) Option {
return (*timeout)(&t)
}

func (t *timeout) apply(opts *options) {
opts.SetTimeout(time.Duration(*t))
}
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package gout

// Version show version
const Version = "v0.2.0"
const Version = "v0.2.1"

0 comments on commit 732cbb9

Please sign in to comment.