package resource_pool import ( "sync/atomic" "errors" ) // A resource handle managed by a resource pool. type ManagedHandle interface { // This returns the handle's resource location. ResourceLocation() string // This returns the underlying resource handle (or error if the handle // is no longer active). Handle() (interface{}, error) // This returns the resource pool which owns this handle. Owner() ResourcePool // The releases the underlying resource handle to the caller and marks the // managed handle as inactive. The caller is responsible for cleaning up // the released handle. This returns nil if the managed handle no longer // owns the resource. ReleaseUnderlyingHandle() interface{} // This indictes a user is done with the handle and releases the handle // back to the resource pool. Release() error // This indicates the handle is an invalid state, and that the // connection should be discarded from the connection pool. Discard() error } // A physical implementation of ManagedHandle type managedHandleImpl struct { location string handle interface{} pool ResourcePool isActive int32 // atomic bool options Options } // This creates a managed handle wrapper. func NewManagedHandle( resourceLocation string, handle interface{}, pool ResourcePool, options Options) ManagedHandle { h := &managedHandleImpl{ location: resourceLocation, handle: handle, pool: pool, options: options, } atomic.StoreInt32(&h.isActive, 1) return h } // See ManagedHandle for documentation. func (c *managedHandleImpl) ResourceLocation() string { return c.location } // See ManagedHandle for documentation. func (c *managedHandleImpl) Handle() (interface{}, error) { if atomic.LoadInt32(&c.isActive) == 0 { return c.handle, errors.New("Resource handle is no longer valid") } return c.handle, nil } // See ManagedHandle for documentation. func (c *managedHandleImpl) Owner() ResourcePool { return c.pool } // See ManagedHandle for documentation. func (c *managedHandleImpl) ReleaseUnderlyingHandle() interface{} { if atomic.CompareAndSwapInt32(&c.isActive, 1, 0) { return c.handle } return nil } // See ManagedHandle for documentation. func (c *managedHandleImpl) Release() error { return c.pool.Release(c) } // See ManagedHandle for documentation. func (c *managedHandleImpl) Discard() error { return c.pool.Discard(c) }