Import (
"Errors"
"FMT"
"Github.com/gohouse/gorose
""Sync"
"Time"
)
//frequently create and close the connection, the system can be quite a burden
//so we need a pool, it has been a fixed number of prior to create connection resources, need to take, when does not need to be returned to the pool,
//but connection resources has a characteristic, we can't guarantee the connection will be effective for a long time,
//, for example, the network reasons, human factors, etc can all result in a connection failure,
//so we set a timeout, if the connection is time difference between the current time more than timeout, then close the connection,
The type Factory struct {
Conn * gorose Connection
Err error
}
Func (factory * factory), Close () {
Factory. Conn. Close ()
}
Func (factory * factory) factory () (conn * gorose Connection, err error) {
Return the factory. The conn, factory. Err
}
//the factory method, is used to create connections resources
Func NewConn () (the factory factory) {
Var dbConfig=& amp; Gorose. DbConfigSingle {
Driver: "mysql",//Driver: mysql/sqlite/oracle/MSSQL/postgres
EnableQueryLog: true,//if the enable SQL logs
SetMaxOpenConns: 0,//the connection pool of Max Open connections, default zero
SetMaxIdleConns: 0,//the connection pool of Max sleep connections
The Prefix: "",//the Prefix of table
Dsn: "root: a root @ TCP (localhost: 3306/test? Charset=utf8 ",//db DSN
}
//initialize the database link, the default specified in the configuration of the default link value
//in the second parameter is specified in the corresponding database links, see comments below the line that links the sample
Connection, err:=gorose. Open (dbConfig)
Return the Factory {connection, err}
}
//connection
Type the Conn struct {
Conn * gorose Connection
//connection time
Time time. Time
}
//the connection pool
Type ConnPool struct {
//the mutex to ensure the safety of resources
Mu sync. Mutex
//channel, save all the connection resources
Conns chan * Conn
//the factory method, create a connection resources
The factory factory
//determine whether pool closed
Closed bool
//connection timeout
ConnTimeOut time. Duration
}
//create a connection pool
Func NewConnPool (factory factory, cap int, connTimeOut time, Duration) (* ConnPool, error) {
If cap & lt;=0 {
Return nil, errors. The New (" cap can't less than 0 ")
}
If connTimeOut & lt;=0 {
Return nil, errors. The New (" connTimeOut cannot be less than 0 ")
}
Cp:=& amp; ConnPool {
Mu: sync. Mutex {},
Conns: make (chan * Conn, cap),
Factory: factory,
Closed: false,
ConnTimeOut: connTimeOut,
}
For I:=0; i
NewConn:=newConn ()
Conn1, err:=newConn. Factory ()
if err ! Nil={
Cp. The Close ()
Return nil, errors. The New (error "factory")
}
//insert the connection resources channel
Cp. Conns & lt; - & amp; Conn {Conn: conn1, time: the time Now ()}
}
Return the cp, nil
}
//get connection resources
Func (cp * ConnPool) Get () (* gorose in Connection, the error) {
If the cp. Closed {
Return nil, errors. The New (" connection pool closed ")
}
For {
The select {
//get connection from channel resources
Case connRes, ok:=& lt; - cp. Conns:
{
if ! Ok {
Return nil, errors. The New (" connection pool closed ")
}
//connect judgment in time, if the timeout, the closed
//to get
If the time. Now (). Sub (connRes. Time) & gt; Cp. ConnTimeOut {
ConnRes. Conn. Close ()
The continue
}
Return connRes conn, nil
}
Default:
{
//if you can't access to resources, from the channel is to create a resource returns
NewConn:=newConn ()
ConnRes, err:=newConn. Factory ()
if err ! Nil={
Return nil, err
}
Return connRes, nil
}
}
}
}
//connection resources back into the pool
Func (cp * ConnPool) Put (conn * gorose Connection) error {
If the cp. Closed {
Return errors. The New (" connection pool closed ")
}
The select {
//to add to the channel resources
Case the cp. Conns & lt; - & amp; Conn {Conn: Conn, time: the time Now ()} :
{
Return nil
}
Default:
{
//if unable to join, then close the connection
Conn. Close ()
Return errors. The New (" connection pool is full ")
}
}
}
//close the connection pool
Func (cp * ConnPool) Close () {
If the cp. Closed {
Return
}
Cp. Mu. The Lock ()
Cp. Closed=true
//close the channel
Close (cp. Conns)
//the loop closed channel
For conn: the range of=cp conns {
Conn. Conn. Close ()
}
Cp. Mu. Unlock ()
}
//returns the length of the pool channel
Func (cp * ConnPool) len (int) {
Return len (cp) conns)
}
Func main () {
Cp, _ :=NewConnPool (NewConn (), 10, and time. The Second * 10)
//access to resources
Conn1, _ :=cp. The Get ()
Conn2, _ :=cp. The Get ()
//here in the pool resources size is 8
FMT. Println (" cp len: ", cp. Len ())
//var session * gorose Connection
The session:=conn1 NewSession ()
Res, err:=session. The Table (" users "). The First ()
If err! Nil={
FMT. Println (" db Table ", err)
Return
}
FMT. Println (res)
//connect two resources back into the pool
Cp. The Put (conn1)
Cp. The Put (conn2)
//here is shown as 3
FMT. Println (" cp len: ", cp. Len ())
Cp. The Close ()
}
CodePudding user response:
HTTP and SQL are bringing the connection poolCodePudding user response:
SQL library own connection pool...CodePudding user response:
HTTP and SQL are bringing the connection poolCodePudding user response:
Connection pool is not the problem, the biggest problem is how to connect with the current context binding, which is similar to Java thread binding with connections, ensure that the current multiple database will have the same connections