golang通用連接池的實現(xiàn)

golang的channel除了goroutine通信之外還有很多其他的功能,本文將實現(xiàn)一種基于channel的通用連接池。

何為通用?

連接池的實現(xiàn)不依賴具體的實例,而依賴某個接口,本文的連接池選用的是?io.Closer?接口,只要是實現(xiàn)了該接口的對象都可以被池管理。

當(dāng)然,你可以實現(xiàn)基于?interface{}?的連接池,這樣任何對象都可以被管理。

實現(xiàn)原理

將連接句柄存入channel中,由于緩存channel的特性,獲取連接時如果池中有連接,將直接返回,如果池中沒有連接,將阻塞或者新建連接(沒超過最大限制的情況下)。

由于面向接口編程,所有創(chuàng)建連接的邏輯是不清楚的,這里需要傳入一個函數(shù),該函數(shù)返回一個?io.Closer?對象。

實現(xiàn)

由于并發(fā)問題,在需要操作池中互斥數(shù)據(jù)的時候需要加鎖。

package pool

import (

"errors"

"io"

"sync"

"time"

)

var(

ErrInvalidConfig=errors.New("invalid pool config")

ErrPoolClosed=errors.New("pool closed")

)

type factory func()(io.Closer,error)

type Pool interface{

Acquire()(io.Closer,error)//獲取資源

? Release(io.Closer)error? //釋放資源

? Close(io.Closer)error? //關(guān)閉資源

? Shutdown()error? //關(guān)閉池

}

type GenericPool struct{

sync.Mutex

? pool? chan io.Closer

? maxOpen int? //池中最大值

? numOpen? ? int? ? ? //池中資源數(shù)

? minOpen int? ? //池中最小值

? closed bool? ? //池是否關(guān)閉

? maxLifeTime time.Duration

? factory factory //創(chuàng)建連接的方法

}

func NewGenericPool(minOpen,maxOpen int,maxLifetime time.Duration,factory factory)(*GenericPool,error){

if maxOpen<=0||minOpen>maxOpen{

return nil,ErrInvalidConfig

? }

p:=&GenericPool{

pool:make(chan io.Closer,maxOpen),

maxOpen:maxOpen,

minOpen:minOpen,

maxLifeTime:maxLifetime,

factory:factory,

}

for i:=0;i

closer,err:=factory()

if err!=nil{

continue

? ? ? }

p.numOpen++

p.pool<-closer

? }

return p,nil

}

func (p *GenericPool)Acquire()(io.Closer,error){

if p.closed{

return nil,ErrPoolClosed

? }

for? {

closer,err:=p.getOrCreate()

if err!=nil{

return nil,err

? ? ? }

return closer,nil

? }

}

func(p *GenericPool)getOrCreate()(io.Closer,error){

select{

case closer:=<-p.pool:

return closer,nil

? default:

}

p.Lock()

if p.numOpen>=p.maxOpen{

closer:=<-p.pool

? ? ? p.Unlock()

return closer,nil

? }

//新建連接

? closer,err:=p.factory()

if err!=nil{

p.Unlock()

return nil,err

? }

p.numOpen++

p.Unlock()

return closer,nil

}

//釋放單個資源到連接池

func (p *GenericPool)Release(closer io.Closer)error{

if p.closed? ? {

return ErrPoolClosed

? }

p.Lock()

p.pool<-closer

? p.Unlock()

return nil

}

//關(guān)閉單個資源

func (p *GenericPool)Close(closer io.Closer)error{

p.Lock()

closer.Close()

p.numOpen--

p.Unlock()

return nil

}

//關(guān)閉連接池,釋放所有資源

func(p *GenericPool)ShutDown()error{

if p.closed{

return? ErrPoolClosed

? }

p.Lock()

close(p.pool)

for closer:=range p.pool{

closer.Close()

p.numOpen--

}

p.closed=true

? p.Unlock()

return nil

}

基于該連接池,可以管理所有?io.Closer?對象。比如?memcached?,?redis?等等,非常方便!

————————————————

版權(quán)聲明:本文為CSDN博主「貓哭」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/mengxinghuiku/java/article/details/79730871

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容