1

I need to find an effective way to attempt a reconnection , using go-xorm library. Currently if a disconnection occurs , the connection is lost and further queries fail , even if the database comes back online after some time.

Does xorm generate an event on disconnection ?? If so , how can I listen for this event.

My idea was to listen for a disconnection even in a go routine , via a channel .. and fire a reconnection logic (Close current session and current Engine and recreate a new engine and a session on top of it. )

If xorm does not generate a disconnection event , I would have to ping the db at intervals to check for errors .. which I want to avoid.

Currently I'm making a connection in the folllowing way :-

func (sql *SQL) Connect() error {
    var err error
    sql.engine, err = xorm.NewEngine(sql.config.Sql.Engine, sql.config.Sql.Url)
    // sql.engine.SetMaxOpenConns(1)
    // sql.engine.SetMaxIdleConns(1)
    // Use a single connect across this instance apart for transactions
    sql.session = sql.engine.NewSession()
    go monitorConnection(sql, sql.config.Sql.Engine, sql.config.Sql.Url)
    return err
}

func refresh(sql *SQL, engine string, url string) (err error) {
    sql.session.Close()
    sql.engine.Close()
    sql.engine = nil
    sql.session = nil

    sql.engine, err = xorm.NewEngine(engine, url)
    sql.session = sql.engine.NewSession()
    return err
}

func monitorConnection(sql *SQL, engine string, url string) {
    var err error

    for {
        err = sql.engine.Ping()
        if err != nil {
            refresh(sql, engine, url)
        }
        time.Sleep(time.Duration(1000) * time.Millisecond)
    }
}

The config is filled up via other functions.

So currently the only way I feel I can implement the reconnection is by pinging the db in a separate routine constantly until an error occurs, and then close the current session and engine and create new ones.

Can this be done in a better way , making it event based ?

Do I have to create a new engine and session every time ?

Or is there a better way to handle all of this , using go-xorm ?

  • use connection pooling, research and use this as reference it may help: https://stackoverflow.com/questions/38454970/connection-pooling-with-xorm-and-go-mysql – Jorge Campos Apr 30 '19 at 07:55
  • connection pooling still does not solve the problem of a complete db disconnection. – Shourie Ganguly Apr 30 '19 at 09:06
  • The whole purpose of a connection pool is to prevent the application from running out of connections, it will keep a configured number of connections always open in idle state when not in use, so yes, it solves the problem. – Jorge Campos Apr 30 '19 at 15:53
  • 1
    But in my case I am not running out of connections. For example the database server shuts down . Now from my applications perspective the network connection to the db server is broken. Here how will a pool help ? Because logically all open connections in the pool will become invalid. DB server comes back online after 15 mins. The current connections in the pool will still be invalid unless I reset the connection object by making a new connection object. This is my scenario. – Shourie Ganguly May 02 '19 at 13:25
  • 1
    So indeed a connection pool will not help in an disaster event. You should be more specific on your question. Add this information that you want to prevent a disaster scenario (ie database fail). Though a connection pool will not help with the disaster event it will make it easy (if it is implemented correctly) to handle this kind of error and a good connection pool will itself handle the re-connection for you (refresh, retry to connect). Your application would only need to check if there are available connections. This handling is and should be abstracted from your code base. – Jorge Campos May 02 '19 at 15:58

0 Answers0