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
 }