]> 127.0.0.1 Git - part/.git/commitdiff
1 (#60) v0.28.20250528161452
authorqydysky <qydysky@foxmail.com>
Wed, 28 May 2025 16:14:44 +0000 (00:14 +0800)
committerGitHub <noreply@github.com>
Wed, 28 May 2025 16:14:44 +0000 (00:14 +0800)
* 1

* 1

* 1

* 1

reqf/Reqf.go
reqf/Reqf_test.go

index 09d0e9e4db6a5d6c08bab821cec925e17b9ab5cc..22cdcee3f7522aa317d744f91a56eb368fe6d570 100644 (file)
@@ -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)
index a03500762bc08b1e25f829b740e92a22d17d7e7b..c646d76b9d88a439fdff66d871156bc91d9a7737 100644 (file)
@@ -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{