Fix deadlock (#11244)

This PR uses a go routine when sending would otherwise block.
This commit is contained in:
andig 2023-12-26 23:08:28 +01:00 • committed by GitHub
parent b275af9178
commit 55df2b502c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 6 deletions

View file

@ -384,8 +384,20 @@ func (lp *Loadpoint) pushEvent(event string) {
// publish sends values to UI and databases
func (lp *Loadpoint) publish(key string, val interface{}) {
if lp.uiChan != nil {
lp.uiChan <- util.Param{Key: key, Val: val}
// test helper
if lp.uiChan == nil {
return
}
p := util.Param{Key: key, Val: val}
// https://github.com/evcc-io/evcc/issues/11191 prevent deadlock
select {
case lp.uiChan <- p:
default:
go func() {
lp.uiChan <- p
}()
}
}

View file

@ -526,6 +526,7 @@ func cacheExpecter(t *testing.T, lp *Loadpoint) (*util.Cache, func(key string, v
go cache.Run(paramC)
expect := func(key string, val interface{}) {
time.Sleep(100 * time.Millisecond) // wait for cache to catch up
p := cache.Get(key)
t.Logf("%s: %.f", key, p.Val) // REMOVE
if p.Val != val {

View file

@ -360,9 +360,15 @@ func (site *Site) publish(key string, val interface{}) {
val = s.String()
}
site.uiChan <- util.Param{
Key: key,
Val: val,
p := util.Param{Key: key, Val: val}
// https://github.com/evcc-io/evcc/issues/11191 prevent deadlock
select {
case site.uiChan <- p:
default:
go func() {
site.uiChan <- p
}()
}
}

View file

@ -20,7 +20,7 @@ type Tee struct {
func (t *Tee) Attach() <-chan Param {
// TODO find better approach to prevent deadlocks
// this will buffer the receiver channel to prevent deadlocks when consumers use mutex-protected loadpoint api
out := make(chan Param, 16)
out := make(chan Param, 128)
t.add(out)
return out
}