aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kiryukhin <a.kiryukhin@mail.ru>2019-06-15 10:20:37 +0300
committerAlexander Kiryukhin <a.kiryukhin@mail.ru>2019-06-15 10:20:37 +0300
commit741cf397a9150a8f76b8f74289b1dde8aaa43d02 (patch)
tree66a64d97e247b57b37d82493eb307d1bf64c7490
parentc691d422395cb72283512d8956a255db10b70b44 (diff)
WIP: Added lifecycle mixin
Removed hooks
-rwxr-xr-xREADME.md13
-rwxr-xr-xmixins.go14
-rwxr-xr-xrutina.go54
3 files changed, 38 insertions, 43 deletions
diff --git a/README.md b/README.md
index fa1a88f..c6eceab 100755
--- a/README.md
+++ b/README.md
@@ -96,9 +96,9 @@ err := <- r.Errors()
Disabled by default. Use `r.With(rutina.WithErrChan())` to turn on.
-## Events and hooks
+## Lifecycle events
-Rutina has own simple lifecycle events system. You can subscribe your hooks on any of this events:
+Rutina has own simple lifecycle events:
* `EventRoutineStart` - Fires when starts new routine
* `EventRoutineStop` - Fires when routine stopped with any result
@@ -108,15 +108,6 @@ Rutina has own simple lifecycle events system. You can subscribe your hooks on a
* `EventAppComplete` - Fires when all routines stopped with no errors
* `EventAppFail` - Fires when all routines stopped with error
-Example:
-
-```go
-r.RegisterHook(rutina.EventRoutineStart, func(ev rutina.Event, rid int) error {
- log.Println("Started routine with ID", rid)
- return nil
-})
-```
-
## Mixins
### Usage
diff --git a/mixins.go b/mixins.go
index 6688f36..1344d07 100755
--- a/mixins.go
+++ b/mixins.go
@@ -58,3 +58,17 @@ func WithErrChan() *MixinErrChan {
func (o MixinErrChan) apply(r *Rutina) {
r.errCh = make(chan error, 1)
}
+
+type LifecycleListener func(event Event, routineID int)
+
+type LifecycleMixin struct {
+ Listener LifecycleListener
+}
+
+func (l LifecycleMixin) apply(r *Rutina) {
+ r.lifecycleListener = l.Listener
+}
+
+func WithLifecycleListener(listener LifecycleListener) *LifecycleMixin {
+ return &LifecycleMixin{Listener: listener}
+}
diff --git a/rutina.go b/rutina.go
index e4ef1a7..dccce9e 100755
--- a/rutina.go
+++ b/rutina.go
@@ -12,23 +12,23 @@ import (
//Rutina is routine manager
type Rutina struct {
- ctx context.Context // State of application (started/stopped)
- Cancel func() // Cancel func that stops all routines
- wg sync.WaitGroup // WaitGroup that wait all routines to complete
- onceErr sync.Once // Flag that prevents overwrite first error that shutdowns all routines
- onceWait sync.Once // Flag that prevents wait already waited rutina
- err error // First error that shutdowns all routines
- logger *log.Logger // Optional logger
- counter *uint64 // Optional counter that names routines with increment ids for debug purposes at logger
- errCh chan error // Optional channel for errors when RestartIfFail and DoNothingIfFail
- hooks map[Event][]Hook // Lifecycle hooks
+ ctx context.Context // State of application (started/stopped)
+ Cancel func() // Cancel func that stops all routines
+ wg sync.WaitGroup // WaitGroup that wait all routines to complete
+ onceErr sync.Once // Flag that prevents overwrite first error that shutdowns all routines
+ onceWait sync.Once // Flag that prevents wait already waited rutina
+ err error // First error that shutdowns all routines
+ logger *log.Logger // Optional logger
+ counter *uint64 // Optional counter that names routines with increment ids for debug purposes at logger
+ errCh chan error // Optional channel for errors when RestartIfFail and DoNothingIfFail
+ lifecycleListener LifecycleListener // Optional listener for events
}
// New instance with builtin context
func New(mixins ...Mixin) *Rutina {
ctx, cancel := context.WithCancel(context.Background())
var counter uint64
- r := &Rutina{ctx: ctx, Cancel: cancel, counter: &counter, errCh: nil, hooks: map[Event][]Hook{}}
+ r := &Rutina{ctx: ctx, Cancel: cancel, counter: &counter, errCh: nil}
return r.With(mixins...)
}
@@ -40,10 +40,6 @@ func (r *Rutina) With(mixins ...Mixin) *Rutina {
return r
}
-func (r *Rutina) RegisterHook(ev Event, hook Hook) {
- r.hooks[ev] = append(r.hooks[ev], hook)
-}
-
// Go routine
func (r *Rutina) Go(doer func(ctx context.Context) error, opts ...Options) {
// Check that context is not canceled yet
@@ -77,10 +73,10 @@ func (r *Rutina) Go(doer func(ctx context.Context) error, opts ...Options) {
go func() {
defer r.wg.Done()
id := atomic.AddUint64(r.counter, 1)
- r.fire(EventRoutineStart, int(id))
+ r.lifecycleEvent(EventRoutineStart, int(id))
if err := doer(r.ctx); err != nil {
- r.fire(EventRoutineFail, int(id))
- r.fire(EventRoutineStop, int(id))
+ r.lifecycleEvent(EventRoutineFail, int(id))
+ r.lifecycleEvent(EventRoutineStop, int(id))
// errors history
if r.errCh != nil {
r.errCh <- err
@@ -98,8 +94,8 @@ func (r *Rutina) Go(doer func(ctx context.Context) error, opts ...Options) {
}
// endregion
} else {
- r.fire(EventRoutineComplete, int(id))
- r.fire(EventRoutineStop, int(id))
+ r.lifecycleEvent(EventRoutineComplete, int(id))
+ r.lifecycleEvent(EventRoutineStop, int(id))
// region routine successfully done
switch onDone {
case ShutdownIfDone:
@@ -140,11 +136,11 @@ func (r *Rutina) ListenOsSignals(signals ...os.Signal) {
func (r *Rutina) Wait() error {
r.onceWait.Do(func() {
r.wg.Wait()
- r.fire(EventAppStop, 0)
+ r.lifecycleEvent(EventAppStop, 0)
if r.err == nil {
- r.fire(EventAppComplete, 0)
+ r.lifecycleEvent(EventAppComplete, 0)
} else {
- r.fire(EventAppFail, 0)
+ r.lifecycleEvent(EventAppFail, 0)
}
if r.errCh != nil {
close(r.errCh)
@@ -153,16 +149,10 @@ func (r *Rutina) Wait() error {
return r.err
}
-func (r *Rutina) fire(ev Event, rid int) {
+func (r *Rutina) lifecycleEvent(ev Event, rid int) {
r.log("Event = %s Routine ID = %d", ev.String(), rid)
- if hooks, ok := r.hooks[ev]; ok == true {
- for _, h := range hooks {
- if err := h(ev, r, rid); err != nil {
- if r.errCh != nil {
- r.errCh <- err
- }
- }
- }
+ if r.lifecycleListener != nil {
+ r.lifecycleListener(ev, rid)
}
}