aboutsummaryrefslogtreecommitdiff
path: root/rutina.go
diff options
context:
space:
mode:
authorAlexander Kiryukhin <alexander@kiryukhin.su>2018-12-05 00:48:33 +0300
committerAlexander Kiryukhin <alexander@kiryukhin.su>2018-12-05 00:48:33 +0300
commitc582001e89c0b81df1b9eb1e8f1857d1c075a805 (patch)
tree1269ce0169824e967e0eccc83c257f2a2ab9f445 /rutina.go
parent381df5413c2be2a183945aa334ff1690a2cdfb0c (diff)
Initial commit
Diffstat (limited to 'rutina.go')
-rwxr-xr-xrutina.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/rutina.go b/rutina.go
new file mode 100755
index 0000000..68bf048
--- /dev/null
+++ b/rutina.go
@@ -0,0 +1,54 @@
+package rutina
+
+import (
+ "context"
+ "sync"
+)
+
+//Rutina is routine manager
+type Rutina struct {
+ ctx context.Context
+ cancel func()
+ wg sync.WaitGroup
+ o sync.Once
+ err error
+}
+
+// New instance with builtin context
+func New() (*Rutina, context.Context) {
+ return WithContext(context.Background())
+}
+
+// WithContext is constructor that takes context from outside
+func WithContext(ctx context.Context) (*Rutina, context.Context) {
+ ctx, cancel := context.WithCancel(ctx)
+
+ return &Rutina{ctx: ctx, cancel: cancel}, ctx
+}
+
+// Go routine
+func (r *Rutina) Go(doer func(ctx context.Context) error) {
+ r.wg.Add(1)
+ go func() {
+ defer func() {
+ r.wg.Done()
+ if r.cancel != nil {
+ r.cancel()
+ }
+ }()
+ if err := doer(r.ctx); err != nil {
+ r.o.Do(func() {
+ r.err = err
+ })
+ }
+ }()
+}
+
+// Wait all routines and returns first error or nil if all routines completes without errors
+func (r *Rutina) Wait() error {
+ r.wg.Wait()
+ if r.cancel != nil {
+ r.cancel()
+ }
+ return r.err
+}