github.com/pubgo/xprocess@v0.1.11/process.go (about) 1 package xprocess 2 3 import ( 4 "context" 5 "fmt" 6 "runtime" 7 "time" 8 9 "github.com/pubgo/xerror" 10 "github.com/pubgo/xlog" 11 "github.com/pubgo/xprocess/xprocess_errs" 12 "go.uber.org/zap" 13 ) 14 15 func Break() { panic(xprocess_errs.ErrBreak) } 16 17 type process struct{} 18 19 func (t *process) memStatsPrint() { 20 var m runtime.MemStats 21 runtime.ReadMemStats(&m) 22 fmt.Printf("HeapAlloc = %v HeapIdel= %v HeapSys = %v HeapReleased = %v\n", m.HeapAlloc/1024, m.HeapIdle/1024, m.HeapSys/1024, m.HeapReleased/1024) 23 } 24 25 func (t *process) costWith(fn func()) (dur time.Duration) { 26 xerror.Assert(fn == nil, "[fn] should not be nil") 27 28 defer func(start time.Time) { dur = time.Since(start) }(time.Now()) 29 30 fn() 31 return 32 } 33 34 func (t *process) count(n int) <-chan int { 35 var c = make(chan int) 36 go func() { 37 defer close(c) 38 for i := 0; i < n; i++ { 39 c <- i 40 } 41 }() 42 return c 43 } 44 45 // tick 简单定时器 46 // Example: tick(100, time.Second) 47 func (t *process) tick(args ...interface{}) <-chan time.Time { 48 var n int 49 var dur time.Duration 50 51 for _, arg := range args { 52 xerror.Assert(arg == nil, "[arg] should not be nil") 53 54 switch ag := arg.(type) { 55 case int: 56 n = ag 57 case time.Duration: 58 dur = ag 59 } 60 } 61 62 if n <= 0 { 63 n = 1 64 } 65 66 if dur <= 0 { 67 dur = time.Second 68 } 69 70 var c = make(chan time.Time) 71 go func() { 72 defer close(c) 73 74 tk := time.NewTicker(dur) 75 for i := 0; ; i++ { 76 if i == n { 77 tk.Stop() 78 break 79 } 80 81 c <- <-tk.C 82 } 83 }() 84 85 return c 86 } 87 88 func (t *process) try(fn func()) (err error) { 89 defer xerror.RespErr(&err) 90 fn() 91 return 92 } 93 94 func (t *process) goCtx(fn func(ctx context.Context)) context.CancelFunc { 95 xerror.Assert(fn == nil, "[fn] should not be nil") 96 97 ctx, cancel := context.WithCancel(context.Background()) 98 go func() { 99 defer cancel() 100 defer xerror.Resp(func(err xerror.XErr) { xlog.Error("process.goCtx error", zap.Any("err", err)) }) 101 102 fn(ctx) 103 }() 104 105 return cancel 106 } 107 108 func (t *process) goLoopCtx(fn func(ctx context.Context)) context.CancelFunc { 109 xerror.Assert(fn == nil, "[fn] should not be nil") 110 111 ctx, cancel := context.WithCancel(context.Background()) 112 go func() { 113 defer cancel() 114 defer xerror.Resp(func(err xerror.XErr) { 115 if xerror.Unwrap(err) == xprocess_errs.ErrBreak { 116 return 117 } 118 119 xlog.Error("process.goLoopCtx error", zap.Any("err", err)) 120 }) 121 122 for { 123 select { 124 case <-ctx.Done(): 125 return 126 default: 127 fn(ctx) 128 } 129 } 130 }() 131 132 return cancel 133 } 134 135 func (t *process) goWithTimeout(dur time.Duration, fn func(ctx context.Context)) (gErr error) { 136 defer xerror.RespErr(&gErr) 137 138 xerror.Assert(dur <= 0, "[dur] should not be less than zero") 139 xerror.Assert(fn == nil, "[fn] should not be nil") 140 141 ctx, cancel := context.WithCancel(context.Background()) 142 defer cancel() 143 144 var ch = make(chan struct{}) 145 go func() { 146 defer close(ch) 147 defer xerror.RespErr(&gErr) 148 149 fn(ctx) 150 }() 151 152 select { 153 case <-ch: 154 return 155 case <-time.After(dur): 156 return xprocess_errs.ErrTimeout 157 } 158 } 159 160 func (t *process) goWithDelay(dur time.Duration, fn func()) (gErr error) { 161 defer xerror.RespErr(&gErr) 162 163 xerror.Assert(dur <= 0, "[dur] should not be less than zero") 164 xerror.Assert(fn == nil, "[fn] should not be nil") 165 166 go func() { 167 defer xerror.Resp(func(err xerror.XErr) { 168 dur = 0 169 gErr = err.WrapF("process.goWithDelay error") 170 }) 171 172 fn() 173 }() 174 175 if dur != 0 { 176 time.Sleep(dur) 177 } 178 179 return 180 }