managed_handle.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package resource_pool
  2. import (
  3. "sync/atomic"
  4. "errors"
  5. )
  6. // A resource handle managed by a resource pool.
  7. type ManagedHandle interface {
  8. // This returns the handle's resource location.
  9. ResourceLocation() string
  10. // This returns the underlying resource handle (or error if the handle
  11. // is no longer active).
  12. Handle() (interface{}, error)
  13. // This returns the resource pool which owns this handle.
  14. Owner() ResourcePool
  15. // The releases the underlying resource handle to the caller and marks the
  16. // managed handle as inactive. The caller is responsible for cleaning up
  17. // the released handle. This returns nil if the managed handle no longer
  18. // owns the resource.
  19. ReleaseUnderlyingHandle() interface{}
  20. // This indicates a user is done with the handle and releases the handle
  21. // back to the resource pool.
  22. Release() error
  23. // This indicates the handle is an invalid state, and that the
  24. // connection should be discarded from the connection pool.
  25. Discard() error
  26. }
  27. // A physical implementation of ManagedHandle
  28. type managedHandleImpl struct {
  29. location string
  30. handle interface{}
  31. pool ResourcePool
  32. isActive int32 // atomic bool
  33. options Options
  34. }
  35. // This creates a managed handle wrapper.
  36. func NewManagedHandle(
  37. resourceLocation string,
  38. handle interface{},
  39. pool ResourcePool,
  40. options Options) ManagedHandle {
  41. h := &managedHandleImpl{
  42. location: resourceLocation,
  43. handle: handle,
  44. pool: pool,
  45. options: options,
  46. }
  47. atomic.StoreInt32(&h.isActive, 1)
  48. return h
  49. }
  50. // See ManagedHandle for documentation.
  51. func (c *managedHandleImpl) ResourceLocation() string {
  52. return c.location
  53. }
  54. // See ManagedHandle for documentation.
  55. func (c *managedHandleImpl) Handle() (interface{}, error) {
  56. if atomic.LoadInt32(&c.isActive) == 0 {
  57. return c.handle, errors.New("Resource handle is no longer valid")
  58. }
  59. return c.handle, nil
  60. }
  61. // See ManagedHandle for documentation.
  62. func (c *managedHandleImpl) Owner() ResourcePool {
  63. return c.pool
  64. }
  65. // See ManagedHandle for documentation.
  66. func (c *managedHandleImpl) ReleaseUnderlyingHandle() interface{} {
  67. if atomic.CompareAndSwapInt32(&c.isActive, 1, 0) {
  68. return c.handle
  69. }
  70. return nil
  71. }
  72. // See ManagedHandle for documentation.
  73. func (c *managedHandleImpl) Release() error {
  74. return c.pool.Release(c)
  75. }
  76. // See ManagedHandle for documentation.
  77. func (c *managedHandleImpl) Discard() error {
  78. return c.pool.Discard(c)
  79. }