v0.0.602 add listener to DelayedCombiningInvoker
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m18s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 2m18s
This commit is contained in:
@@ -2,10 +2,11 @@ package dataext
|
||||
|
||||
import (
|
||||
"context"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/syncext"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/langext"
|
||||
"git.blackforestbytes.com/BlackForestBytes/goext/syncext"
|
||||
)
|
||||
|
||||
type DelayedCombiningInvoker struct {
|
||||
@@ -17,8 +18,13 @@ type DelayedCombiningInvoker struct {
|
||||
delay time.Duration
|
||||
maxDelay time.Duration
|
||||
executorRunning *syncext.AtomicBool
|
||||
pendingRequests *syncext.Atomic[int]
|
||||
lastRequestTime time.Time
|
||||
initialRequestTime time.Time
|
||||
|
||||
onExecutionStart []func(immediately bool) // listener ( actual execution of action starts )
|
||||
onExecutionDone []func() // listener ( actual execution of action finished )
|
||||
onRequest []func(pending int, initial bool) // listener ( a request came in, waiting for execution )
|
||||
}
|
||||
|
||||
func NewDelayedCombiningInvoker(action func(), delay time.Duration, maxDelay time.Duration) *DelayedCombiningInvoker {
|
||||
@@ -27,11 +33,15 @@ func NewDelayedCombiningInvoker(action func(), delay time.Duration, maxDelay tim
|
||||
delay: delay,
|
||||
maxDelay: maxDelay,
|
||||
executorRunning: syncext.NewAtomicBool(false),
|
||||
pendingRequests: syncext.NewAtomic[int](0),
|
||||
triggerChan: make(chan bool),
|
||||
cancelChan: make(chan bool, 1),
|
||||
execNowChan: make(chan bool, 1),
|
||||
lastRequestTime: time.Now(),
|
||||
initialRequestTime: time.Now(),
|
||||
onExecutionStart: make([]func(bool), 0),
|
||||
onExecutionDone: make([]func(), 0),
|
||||
onRequest: make([]func(int, bool), 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +53,11 @@ func (d *DelayedCombiningInvoker) Request() {
|
||||
|
||||
if d.executorRunning.Get() {
|
||||
d.lastRequestTime = now
|
||||
d.pendingRequests.Update(func(v int) int { return v + 1 })
|
||||
|
||||
for _, fn := range d.onRequest {
|
||||
_ = langext.RunPanicSafe(func() { fn(d.pendingRequests.Get(), true) })
|
||||
}
|
||||
|
||||
d.triggerChan <- true
|
||||
} else {
|
||||
@@ -50,9 +65,15 @@ func (d *DelayedCombiningInvoker) Request() {
|
||||
d.lastRequestTime = now
|
||||
|
||||
d.executorRunning.Set(true)
|
||||
d.pendingRequests.Set(1)
|
||||
syncext.ReadNonBlocking(d.triggerChan) // clear the channel
|
||||
syncext.ReadNonBlocking(d.cancelChan) // clear the channel
|
||||
syncext.ReadNonBlocking(d.execNowChan) // clear the channel
|
||||
|
||||
for _, fn := range d.onRequest {
|
||||
_ = langext.RunPanicSafe(func() { fn(d.pendingRequests.Get(), false) })
|
||||
}
|
||||
|
||||
go d.run()
|
||||
}
|
||||
}
|
||||
@@ -98,8 +119,22 @@ func (d *DelayedCombiningInvoker) run() {
|
||||
continue
|
||||
}
|
||||
|
||||
d.pendingRequests.Set(0)
|
||||
|
||||
for _, fn := range d.onExecutionStart {
|
||||
_ = langext.RunPanicSafe(func() { fn(immediately) })
|
||||
}
|
||||
|
||||
// =================================================
|
||||
_ = langext.RunPanicSafe(d.action)
|
||||
// =================================================
|
||||
|
||||
for _, fn := range d.onExecutionDone {
|
||||
_ = langext.RunPanicSafe(fn)
|
||||
}
|
||||
|
||||
d.syncLock.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -115,6 +150,10 @@ func (d *DelayedCombiningInvoker) HasPendingRequests() bool {
|
||||
return d.executorRunning.Get()
|
||||
}
|
||||
|
||||
func (d *DelayedCombiningInvoker) CountPendingRequests() int {
|
||||
return d.pendingRequests.Get()
|
||||
}
|
||||
|
||||
func (d *DelayedCombiningInvoker) ExecuteNow() bool {
|
||||
d.syncLock.Lock()
|
||||
defer d.syncLock.Unlock()
|
||||
@@ -130,3 +169,21 @@ func (d *DelayedCombiningInvoker) ExecuteNow() bool {
|
||||
func (d *DelayedCombiningInvoker) WaitForCompletion(ctx context.Context) error {
|
||||
return d.executorRunning.WaitWithContext(ctx, false)
|
||||
}
|
||||
|
||||
func (d *DelayedCombiningInvoker) RegisterOnExecutionStart(fn func(immediately bool)) {
|
||||
d.syncLock.Lock()
|
||||
defer d.syncLock.Unlock()
|
||||
d.onExecutionStart = append(d.onExecutionStart, fn)
|
||||
}
|
||||
|
||||
func (d *DelayedCombiningInvoker) RegisterOnExecutionDone(fn func()) {
|
||||
d.syncLock.Lock()
|
||||
defer d.syncLock.Unlock()
|
||||
d.onExecutionDone = append(d.onExecutionDone, fn)
|
||||
}
|
||||
|
||||
func (d *DelayedCombiningInvoker) RegisterOnRequest(fn func(pending int, initial bool)) {
|
||||
d.syncLock.Lock()
|
||||
defer d.syncLock.Unlock()
|
||||
d.onRequest = append(d.onRequest, fn)
|
||||
}
|
||||
|
Reference in New Issue
Block a user