github.com/pubgo/xprocess@v0.1.11/README.md (about) 1 # xprocess 2 > 一个通用的机制去管理goroutine的生命周期 3 4 1. 通过xprocess.Go替换原生的直接启动goroutine的方式 5 2. 通过context传递, 管理goroutine的生命周期 6 3. GoLoop是对goroutine中有for的封装和替换 7 4. Group是一个WaitGroup的wrap,不过增加了goroutine统计和可退出机制 8 5. Stack会得到内存中所有在运行的goroutine, 以及数量 9 10 ## Examples 11 12 ```go 13 fmt.Println(xprocess.Stack()) 14 cancel := xprocess.Go(func(ctx context.Context) error { 15 for { 16 select { 17 case <-ctx.Done(): 18 return ctx.Err() 19 default: 20 time.Sleep(time.Millisecond * 100) 21 fmt.Println("g1") 22 } 23 } 24 }) 25 26 time.Sleep(time.Second) 27 fmt.Println(xprocess.Stack()) 28 fmt.Println(cancel()) 29 time.Sleep(time.Second) 30 fmt.Println(xprocess.Stack()) 31 ``` 32 33 ```go 34 fmt.Println(xprocess.Stack()) 35 for { 36 xprocess.Go(func(ctx context.Context) error { 37 time.Sleep(time.Second) 38 fmt.Println("g2") 39 return ctx.Err() 40 }) 41 xprocess.GoLoop(func(ctx context.Context) error { 42 time.Sleep(time.Second) 43 fmt.Println("g3") 44 return ctx.Err() 45 }) 46 47 g := xprocess.NewGroup() 48 g.Go(func(ctx context.Context) error { 49 fmt.Println("g4") 50 return nil 51 }) 52 g.Go(func(ctx context.Context) error { 53 fmt.Println("g5") 54 return nil 55 }) 56 g.Go(func(ctx context.Context) error { 57 fmt.Println("g6") 58 return xerror.Fmt("test error") 59 }) 60 g.Wait() 61 fmt.Println(g.Err()) 62 63 g.Cancel() 64 65 fmt.Println(xprocess.Stack()) 66 time.Sleep(time.Second) 67 } 68 ``` 69 70 ### Timeout 71 ```go 72 func TestTimeout(t *testing.T) { 73 err := xprocess.Timeout(time.Second, func(ctx context.Context) error { 74 time.Sleep(time.Millisecond * 990) 75 return nil 76 }) 77 assert.Nil(t, err) 78 79 err = xprocess.Timeout(time.Second, func(ctx context.Context) error { 80 time.Sleep(time.Second + time.Millisecond*10) 81 return nil 82 }) 83 assert.NotNil(t, err) 84 } 85 ``` 86 87 ### Future 88 89 > async,await,yield 90 91 ```go 92 package xprocess 93 94 import ( 95 "fmt" 96 "net/http" 97 "testing" 98 99 "github.com/pubgo/xerror" 100 ) 101 102 func handleReq(i int) Value { 103 fmt.Println("url", i) 104 return Async(http.Get, "https://www.cnblogs.com") 105 } 106 107 func getData() IFuture { 108 return Future(func(y Yield) { 109 for i := 10; i > 0; i-- { 110 i := i 111 if i <= 3 { 112 return 113 } 114 115 y.Await(handleReq(i), func(resp *http.Response, err error) (*http.Response, error) { 116 xerror.Panic(err) 117 118 resp.Header.Add("test", "11111") 119 return resp, err 120 }) 121 122 y.Yield(Async(http.Get, "https://www.cnblogs.com")) 123 } 124 }) 125 } 126 127 func handleData() IFuture { 128 return Future(func(y Yield) { 129 getData().Value(func(resp *http.Response, err error) { 130 y.Yield(resp.Header) 131 }) 132 }) 133 } 134 135 func TestStream(t *testing.T) { 136 handleData().Value(func(head http.Header) { 137 fmt.Println("dt", head) 138 }) 139 } 140 141 func TestAsync(t *testing.T) { 142 val1 := handleReq(1) 143 val2 := handleReq(2) 144 val3 := handleReq(3) 145 val4 := handleReq(4) 146 147 fmt.Printf("%#v, %#v, %#v, %#v\n", val1.Get(), val2.Get(), val3.Get(), val4.Get()) 148 } 149 150 func TestGetData(t *testing.T) { 151 getData().Value(func(resp *http.Response, err error) { 152 fmt.Println(resp) 153 }) 154 } 155 156 func handleData2() IFuture { 157 return Future(func(y Yield) { 158 for i := 10; i > 0; i-- { 159 y.Yield(i) 160 } 161 }) 162 } 163 164 func TestName11w(t *testing.T) { 165 handleData2().Value(func(i int) { 166 fmt.Println(i) 167 }) 168 } 169 ```