fix(plc4go): speed up close of connection close
diff --git a/plc4go/pkg/api/cache/PlcConnectionCache.go b/plc4go/pkg/api/cache/PlcConnectionCache.go
index 353b482..908e5c1 100644
--- a/plc4go/pkg/api/cache/PlcConnectionCache.go
+++ b/plc4go/pkg/api/cache/PlcConnectionCache.go
@@ -22,6 +22,7 @@
import (
"context"
"fmt"
+ "runtime/debug"
"sync"
"time"
@@ -217,6 +218,7 @@
}
func (c *plcConnectionCache) Close() error {
+ ctx := context.TODO()
c.log.Debug().Msg("Closing connection cache started.")
c.log.Trace().Msg("Acquire lock")
c.cacheLock.Lock()
@@ -228,45 +230,56 @@
return nil
}
+ var wg sync.WaitGroup
for _, connectionContainer := range c.connections {
ccLog := c.log.With().Stringer("connectionContainer", connectionContainer).Logger()
ccLog.Trace().Msg("Closing connection")
// Mark the connection as being closed to not try to re-establish it.
connectionContainer.closed = true
- // Try to get a lease as this way we kow we're not closing the connection
- // while some go func is still using it.
- ccLog.Trace().Msg("getting a lease")
- ctx, cancel := context.WithTimeout(context.TODO(), c.maxWaitTime)
- connChan, errChan := connectionContainer.lease(ctx)
- select {
- // We're just getting the lease as this way we can be sure nobody else is using it.
- // We also really don't care if it worked, or not ... it's just an attempt of being
- // nice.
- case _ = <-connChan:
- ccLog.Debug().Msg("Gracefully closing connection ...")
- // Give back the connection.
- if connectionContainer.connection != nil {
- ccLog.Trace().Msg("closing actual connection")
- if err := connectionContainer.connection.Close(); err != nil {
- ccLog.Debug().Err(err).Msg("Error while closing connection")
+ wg.Go(func() {
+ defer func() {
+ if err := recover(); err != nil {
+ c.log.Error().
+ Str("stack", string(debug.Stack())).
+ Interface("err", err).
+ Msg("panic-ed")
+ }
+ }()
+ // Try to get a lease as this way we kow we're not closing the connection
+ // while some go func is still using it.
+ ccLog.Trace().Msg("getting a lease")
+ ctx, cancel := context.WithTimeout(ctx, c.maxWaitTime)
+ connChan, errChan := connectionContainer.lease(ctx)
+ select {
+ // We're just getting the lease as this way we can be sure nobody else is using it.
+ // We also really don't care if it worked, or not ... it's just an attempt of being
+ // nice.
+ case _ = <-connChan:
+ ccLog.Debug().Msg("Gracefully closing connection ...")
+ // Give back the connection.
+ if connectionContainer.connection != nil {
+ ccLog.Trace().Msg("closing actual connection")
+ if err := connectionContainer.connection.Close(); err != nil {
+ ccLog.Debug().Err(err).Msg("Error while closing connection")
+ }
+ }
+ case err := <-errChan:
+ ccLog.Debug().Err(err).Msg("Error while trying to get lease on connection, ignoring.")
+ // If we're timing out brutally kill the connection.
+ case <-ctx.Done():
+ ccLog.Debug().Msg("Forcefully closing connection ...")
+ // Forcefully close this connection.
+ if connectionContainer.connection != nil {
+ if err := connectionContainer.connection.Close(); err != nil {
+ ccLog.Debug().Err(err).Msg("Error while closing connection")
+ }
}
}
- case err := <-errChan:
- ccLog.Debug().Err(err).Msg("Error while trying to get lease on connection, ignoring.")
- // If we're timing out brutally kill the connection.
- case <-ctx.Done():
- ccLog.Debug().Msg("Forcefully closing connection ...")
- // Forcefully close this connection.
- if connectionContainer.connection != nil {
- if err := connectionContainer.connection.Close(); err != nil {
- ccLog.Debug().Err(err).Msg("Error while closing connection")
- }
- }
- }
- cancel()
-
- c.log.Debug().Msg("Closing connection cache finished.")
+ cancel()
+ })
}
+ wg.Wait()
+ c.log.Debug().Msg("Closing connection cache finished.")
return nil
}