async-pool
Version:
asynchronous event pool based on bluebird
108 lines (86 loc) • 3.12 kB
text/coffeescript
Async Pool
==========
Object that manages a pool of resources, leting resource
users use and then return them so that no resource is used
by more than one user at the same time.
Promise = require 'bluebird'
Logger = require 'logger-facade-nodejs'
log = Logger.getLogger('async-pool')
class AsyncPool
Build a pool. Resources should be an array of resources.
constructor: (resources)->
= resources
= resources?.length ? 0
= []
= null
Get a resource when one comes available. Use with `Promise.using`
Throws a syncrhonous error if there is no pool. Will trigger
any waiting close to reject if used when waiting to close.
use: ()->
self = this
()
return new Promise( (res)->
resource = self.resources.pop()
if resource?
return res(resource)
self.waiting.push(res)
).disposer (resource)->
if self.isClosed()
return
waiter = self.waiting.pop()
if waiter?
waiter(resource)
else
self.resources.push resource
if self.isClosing and resources.length = self.nresources
self.closeImmediate()
Stop managing pool, and don't allow new uses.
Will return synchronously, with "true" if already closed.
If you want to wait for close, then call closeAndWait() -- but beware: if you
wait for closing in a callback that is using a resource, you will hang.
close: ()->
if ?
return false
if !?
return true
if .length ==
= null
return true
else
= true
Close pool, and wait until closed. Be careful -- don't wait if pool is waiting
for you to return a resource!
closeAndWait: ()->
()
if !?
return Promise.resolve(this)
= Promise.defer()
return .promise
Immediately stop managing pool. If there are waiters, throw an
exception.
closeImmediately: ()->
if !?
?.resolve?(this)
= null
return
if > .length
?.reject?('Immediate close while resources still checked out.')
= null
throw new Error('AsyncPool closing while resources still checked out.')
= null
?.resolve?(this)
= null
return this
Returns true if pool closing or is closed.
isClosed: ()->
return !? or ?
Check if closed when used.
_checkCloseOnUse: ()->
if ?
?.reject?(
new Error('AsyncPool used while closing.'))
if !? or ( ) == 0 or ?
= null
= null
throw new Error('AsyncPool is closed or without resources.')
module.exports = AsyncPool