Golang语言社区--golang通用连接池的实现

前端之家收集整理的这篇文章主要介绍了Golang语言社区--golang通用连接池的实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
golang的channel除了goroutine通信之外还有很多其他的功能,本文将实现一种基于channel的通用连接池。
何为通用?
连接池的实现不依赖具体的实例,而依赖某个接口,本文的连接池选用的是io.Closer接口,只要是实现了该接口的对象都可以被池管理。
当然,你可以实现基于interface{}的连接池,这样任何对象都可以被管理。
实现原理
将连接句柄存入channel中,由于缓存channel的特性,获取连接时如果池中有连接,将直接返回,如果池中没有连接,将阻塞或者新建连接(没超过最大限制的情况下)。
由于面向接口编程,所有创建连接的逻辑是不清楚的,这里需要传入一个函数,该函数返回一个io.Closer对象。
实现
由于并发问题,在需要操作池中互斥数据的时候需要加锁。
    @H_403_25@ package pool

  1. import (
  2. "errors"
  3. "io"
  4. "sync"
  5. "time"
  6. )
  7. var (
  8. ErrInvalidConfig = errors.New("invalid pool config")
  9. ErrPoolClosed = errors.New("pool closed")
  10. type factory func() (io.Closer,error)
  11. type Pool interface {
  12. Acquire() (io.Closer,error) // 获取资源
  13. Release(io.Closer) error // 释放资源
  14. Close(io.Closer) error // 关闭资源
  15. Shutdown() error // 关闭
  16. }
  17. type GenericPool struct {
  18. sync.Mutex
  19. pool chan io.Closer
  20. maxOpen int// 池中最大资源数
  21. numOpen int// 当前池中资源数
  22. minOpen int// 池中最少资源数
  23. closed bool // 池是否已关闭
  24. maxLifetime time.Duration
  25. factory factory // 创建连接的方法
  26. func NewGenericPool(minOpen,maxOpen int,maxLifetime time.Duration,factory factory) (*GenericPool,error) {
  27. if maxOpen <= 0 || minOpen > maxOpen {
  28. return nil,ErrInvalidConfig
  29. }
  30. p := &GenericPool{
  31. maxOpen: maxOpen,
  32. minOpen: minOpen,serif;font-size:12px;line-height:1.8em;"> maxLifetime: maxLifetime,serif;font-size:12px;line-height:1.8em;"> factory: factory,serif;font-size:12px;line-height:1.8em;"> pool: make(chan io.Closer,maxOpen),serif;font-size:12px;line-height:1.8em;"> for i := 0; i < minOpen; i++ {
  33. closer,err := factory()
  34. if err != nil {
  35. continue
  36. p.numOpen++
  37. p.pool <- closer
  38. return p,nil
  39. func (p *GenericPool) Acquire() (io.Closer,serif;font-size:12px;line-height:1.8em;"> if p.closed {
  40. for {
  41. return nil,err
  42. // todo maxLifttime处理
  43. return closer,serif;font-size:12px;line-height:1.8em;"> func (p *GenericPool) getOrCreate() (io.Closer,serif;font-size:12px;line-height:1.8em;"> select {
  44. case closer := <-p.pool:
  45. default:
  46. p.Lock()
  47. if p.numOpen >= p.maxOpen {
  48. closer := <-p.pool
  49. p.Unlock()
  50. // 新建连接
  51. // 释放单个资源到连接池
  52. func (p *GenericPool) Release(closer io.Closer) error {
  53. return ErrPoolClosed
  54. return nil
  55. // 关闭单个资源
  56. func (p *GenericPool) Close(closer io.Closer) error {
  57. closer.Close()
  58. p.numOpen--
  59. // 关闭连接池,释放所有资源
  60. func (p *GenericPool) Shutdown() error {
  61. close(p.pool)
  62. for closer := range p.pool {
  63. p.closed = true
  64. }
复制代码
结论
基于该连接池,可以管理所有io.Closer对象。比如memcached,redis等等,非常方便!

Golang语言社区论坛网址:www.golang.ltd

猜你在找的Go相关文章