This is an automated email from the ASF dual-hosted git repository.

sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit a751529f6b6885ce11d8038f35e1e3191e90ee42
Author: Sebastian Rühl <[email protected]>
AuthorDate: Tue Nov 18 09:40:14 2025 +0100

    fix(plc4go): speed up close of connection close
---
 plc4go/pkg/api/cache/PlcConnectionCache.go | 73 ++++++++++++++++++------------
 1 file changed, 43 insertions(+), 30 deletions(-)

diff --git a/plc4go/pkg/api/cache/PlcConnectionCache.go 
b/plc4go/pkg/api/cache/PlcConnectionCache.go
index 353b482211..908e5c1322 100644
--- a/plc4go/pkg/api/cache/PlcConnectionCache.go
+++ b/plc4go/pkg/api/cache/PlcConnectionCache.go
@@ -22,6 +22,7 @@ package cache
 import (
        "context"
        "fmt"
+       "runtime/debug"
        "sync"
        "time"
 
@@ -217,6 +218,7 @@ func (c *plcConnectionCache) GetConnection(ctx 
context.Context, connectionString
 }
 
 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 @@ func (c *plcConnectionCache) Close() error {
                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")
                                }
-                       }
-               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")
+                       }()
+                       // 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")
+                                       }
                                }
                        }
-               }
-               cancel()
-
-               c.log.Debug().Msg("Closing connection cache finished.")
+                       cancel()
+               })
        }
+       wg.Wait()
+       c.log.Debug().Msg("Closing connection cache finished.")
        return nil
 }
 

Reply via email to