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  }