Shourie Ganguly
Shourie Ganguly

Reputation: 46

How to detect database disconnection , and effectively reconnect using go-xorm for databases like mysql, tiDB etc?

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 ?

Upvotes: 1

Views: 2008

Answers (0)

Related Questions