poolcache.go 860 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package poolcache
  2. import (
  3. "context"
  4. "fmt"
  5. "sync"
  6. "github.com/jackc/pgx/v5/pgxpool"
  7. )
  8. type Cache struct {
  9. lock sync.RWMutex
  10. closed bool
  11. pools map[string]*pgxpool.Pool
  12. }
  13. func New() *Cache {
  14. return &Cache{
  15. pools: map[string]*pgxpool.Pool{},
  16. }
  17. }
  18. func (c *Cache) Open(ctx context.Context, uri string) (*pgxpool.Pool, error) {
  19. if c.closed {
  20. return nil, fmt.Errorf("poolcache is closed")
  21. }
  22. c.lock.RLock()
  23. existing, found := c.pools[uri]
  24. c.lock.RUnlock()
  25. if found {
  26. return existing, nil
  27. }
  28. pool, err := pgxpool.New(ctx, uri)
  29. if err != nil {
  30. return nil, err
  31. }
  32. c.lock.Lock()
  33. c.pools[uri] = pool
  34. c.lock.Unlock()
  35. return pool, nil
  36. }
  37. func (c *Cache) Close() error {
  38. c.lock.Lock()
  39. defer c.lock.Unlock()
  40. var closeErr error
  41. for _, pool := range c.pools {
  42. pool.Close()
  43. }
  44. c.closed = true
  45. clear(c.pools)
  46. return closeErr
  47. }