国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Golang > 正文

golang實現基于channel的通用連接池詳解

2020-04-01 18:59:10
字體:
來源:轉載
供稿:網友

前言

golang/196413.html">golang/196412.html">golang的channel除了goroutine通信之外還有很多其他的功能,本文將實現一種基于channel的通用連接池。下面話不多說了,來一起看看詳細的介紹吧。

功能

* 連接池中連接類型為interface{},使得更加通用

* 鏈接的最大空閑時間,超時的鏈接將關閉丟棄,可避免空閑時鏈接自動失效問題

* 使用channel處理池中的鏈接,高效

何為通用?

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

當然,你可以實現基于interface{}的連接池,這樣任何對象都可以被管理。

實現原理

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

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

實現

由于并發問題,在需要操作池中互斥數據的時候需要加鎖。

package poolimport (  "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    // 關閉資源  Shutdown() error       // 關閉池}type GenericPool struct {  sync.Mutex  pool    chan io.Closer  maxOpen   int // 池中最大資源數  numOpen   int // 當前池中資源數  minOpen   int // 池中最少資源數  closed   bool // 池是否已關閉  maxLifetime time.Duration  factory   factory // 創建連接的方法}func NewGenericPool(minOpen, maxOpen int, maxLifetime time.Duration, factory factory) (*GenericPool, error) {  if maxOpen <= 0 || minOpen > maxOpen {    return nil, ErrInvalidConfig  }  p := &GenericPool{    maxOpen:   maxOpen,    minOpen:   minOpen,    maxLifetime: maxLifetime,    factory:   factory,    pool:    make(chan io.Closer, maxOpen),  }  for i := 0; i < minOpen; 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    }    // todo maxLifttime處理    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}// 關閉單個資源func (p *GenericPool) Close(closer io.Closer) error {  p.Lock()  closer.Close()  p.numOpen--  p.Unlock()  return nil}// 關閉連接池,釋放所有資源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等等,非常方便!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳泉市| 巴林左旗| 靖安县| 社旗县| 满城县| 汶川县| 科尔| 读书| 格尔木市| 子长县| 广西| 札达县| 布拖县| 广宁县| 永新县| 商都县| 会泽县| 镇宁| 商丘市| 泽库县| 尉氏县| 阿合奇县| 贡嘎县| 班玛县| 霍州市| 武功县| 通化市| 泰宁县| 宣城市| 虹口区| 克山县| 太谷县| 合水县| 和硕县| 屏东市| 临猗县| 浮山县| 吐鲁番市| 寿宁县| 涞水县| 正宁县|