From 04beb94eedabe28e01741fde42a9bc929258abc0 Mon Sep 17 00:00:00 2001 From: qydysky Date: Thu, 29 May 2025 00:14:44 +0800 Subject: [PATCH] 1 (#60) * 1 * 1 * 1 * 1 --- reqf/Reqf.go | 61 ++++++++++++++++++++++++++++++++++++----------- reqf/Reqf_test.go | 22 +++++++++++++++-- 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/reqf/Reqf.go b/reqf/Reqf.go index 09d0e9e..22cdcee 100644 --- a/reqf/Reqf.go +++ b/reqf/Reqf.go @@ -28,11 +28,15 @@ import ( ) type Rval struct { - Method string - Url string - PostStr string - Proxy string - Retry int + Method string + Url string + + PostStr string + PostByt []byte + PostReader io.Reader + + Proxy string + Retry int // Millisecond,总体请求超时,context.DeadlineExceeded,IsTimeout()==true Timeout int // Millisecond,Retry重试间隔 @@ -91,6 +95,7 @@ type Req struct { responFile *os.File responBuf *bytes.Buffer reqBody io.Reader + allTO *time.Timer rwTO *time.Timer err error callTree string @@ -125,7 +130,10 @@ func (t *Req) reqfM(ctx context.Context, ctxf1 context.CancelCauseFunc, val Rval beginTime := time.Now() for i := 0; i <= val.Retry; i++ { - t.prepareRes(&val) + t.err = t.prepareRes(&val) + if t.err != nil { + break + } t.err = t.reqf(ctx, val) if t.err == nil || IsCancel(t.err) { break @@ -285,7 +293,7 @@ func (t *Req) IsLive() bool { return t.state.Load() == running } -func (t *Req) prepareRes(val *Rval) { +func (t *Req) prepareRes(val *Rval) (e error) { if !val.NoResponse { if t.responBuf == nil { t.responBuf = new(bytes.Buffer) @@ -300,9 +308,10 @@ func (t *Req) prepareRes(val *Rval) { t.Response = nil t.err = nil - if reader, ok := t.reqBody.(*strings.Reader); ok { - reader.Seek(0, io.SeekStart) + if seeker, ok := t.reqBody.(io.Seeker); ok { + _, e = seeker.Seek(0, io.SeekStart) } + return } func (t *Req) prepare(val *Rval) (ctx1 context.Context, ctxf1 context.CancelCauseFunc, e error) { @@ -386,21 +395,45 @@ func (t *Req) prepare(val *Rval) (ctx1 context.Context, ctxf1 context.CancelCaus } if val.RawPipe != nil { t.reqBody = val.RawPipe - } - if len(val.PostStr) > 0 { + } else if len(val.PostStr) > 0 { t.reqBody = strings.NewReader(val.PostStr) + } else if len(val.PostByt) > 0 { + t.reqBody = bytes.NewReader(val.PostByt) + } else if val.PostReader != nil { + t.reqBody = val.PostReader + } else { + t.reqBody = nil } { - var ctx context.Context + var ( + ctx context.Context + cancel context.CancelCauseFunc + ) if val.Ctx != nil { ctx = val.Ctx } else { ctx = context.Background() } + ctx1, cancel = context.WithCancelCause(ctx) if val.Timeout > 0 { - ctx, _ = context.WithTimeout(ctx, time.Duration(val.Timeout)*time.Millisecond) + if t.allTO == nil { + t.allTO = time.NewTimer(time.Duration(val.Timeout) * time.Millisecond) + } + t.allTO.Reset(time.Duration(val.Timeout) * time.Millisecond) + ctxf1 = func(cause error) { + cancel(cause) + t.allTO.Stop() + } + go func() { + select { + case <-t.allTO.C: + ctxf1(context.DeadlineExceeded) + case <-ctx1.Done(): + } + }() + } else { + ctxf1 = cancel } - ctx1, ctxf1 = context.WithCancelCause(ctx) } if t.rwTO == nil { t.rwTO = time.NewTimer(time.Duration(val.CopyResponseTimeout) * time.Millisecond) diff --git a/reqf/Reqf_test.go b/reqf/Reqf_test.go index a035007..c646d76 100644 --- a/reqf/Reqf_test.go +++ b/reqf/Reqf_test.go @@ -134,17 +134,35 @@ func Test_7(t *testing.T) { } func Test_6(t *testing.T) { - reuse.Reqf(Rval{ + if e := reuse.Reqf(Rval{ Url: "http://" + addr + "/header", Header: map[string]string{ `I`: `1`, }, - }) + }); e != nil { + t.Fatal(e) + } if reuse.Response.Header.Get(`I`) != `1` { t.Fail() } } +func Test_8(t *testing.T) { + reuse.Reqf(Rval{ + Url: "http://" + addr + "/reply", + PostStr: "123", + }) + if !bytes.Equal([]byte("123"), reuse.Respon) { + t.Fatal() + } + reuse.Reqf(Rval{ + Url: "http://" + addr + "/reply", + }) + if bytes.Equal([]byte("123"), reuse.Respon) { + t.Fatal() + } +} + // go test -timeout 30s -run ^Test_reuse$ github.com/qydysky/part/reqf -race -count=1 -v -memprofile mem.out func Test_reuse(t *testing.T) { reuse.Reqf(Rval{ -- 2.39.2