Permalink
Browse files

prototype style

  • Loading branch information...
1 parent 3df421d commit 4093f744eaa14bec27919016db3c40f2dda9038e @substack committed Jan 17, 2012
Showing with 107 additions and 99 deletions.
  1. +107 −99 index.js
View
206 index.js
@@ -1,121 +1,129 @@
var EventEmitter = require('events').EventEmitter;
-var Hash = require('hashish');
+var hash = require('hashish');
-module.exports = Resources;
+module.exports = function () {
+ return new Resources;
+}
Resources.prototype = new EventEmitter;
+
function Resources () {
- if (!(this instanceof Resources)) return new Resources();
+ this.resources = {};
+ this.queue = [];
+ this.sessions = {};
+
+ this.stats = {
+ resources : 0,
+ waiting : 0,
+ using : 0
+ };
+}
+
+Resources.prototype.add = function (key, res) {
+ this.resources[key] = {
+ key : key,
+ resource : res,
+ lease : null,
+ emit : null,
+ };
+ this.stats.resources ++;
+ this.emit('stats', this.stats);
+};
+
+Resources.prototype.remove = function (key) {
+ delete this.resources[key];
+ this.emit('stats', this.stats);
+};
+
+Resources.prototype.acquire = function (ms, emit) {
var self = this;
- var resources = self.resources = {};
- var queue = self.queue = [];
- self.using = 0;
+ var token;
+ do {
+ token = Math.floor(Math.random() * Math.pow(2,32)).toString(16);
+ } while (self.sessions[token]);
- self.stats = function () {
- return {
- resources : Object.keys(resources).length,
- waiting : queue.length,
- using : self.using,
- };
- };
+ self.sessions[token] = { emit : emit, time : ms };
- self.add = function (key, res) {
- resources[key] = {
- key : key,
- resource : res,
- lease : null,
- emit : null,
- };
- self.emit('stats', self.stats());
- };
+ emit('token', token);
- self.remove = function (key) {
- delete resources[key];
- self.emit('stats', self.stats());
- };
+ var avail = Object.keys(self.resources).filter(function (key) {
+ return self.resources[key].lease === null;
+ });
+
+ if (avail.length > 0) {
+ self.dispatch(token, avail.values[0]);
+ }
+ else {
+ self.queue.push(token);
+ self.queue.forEach(function (id, i) {
+ self.sessions[id].emit('spot', i + 1, self.queue.length);
+ });
+ self.emit('stats', self.stats);
+ }
- var tokens = {};
- var emitters = {};
+ return token;
+};
+
+Resources.prototype.release = function (token) {
+ var self = this;
+ delete self.tokens[token];
- self.acquire = function (ms, emit) {
- do {
- var token = Math.floor(Math.random() * Math.pow(2,32)).toString(16);
- } while (tokens[token]);
- tokens[token] = true;
+ var ix = self.queue.indexOf(token);
+ if (ix >= 0) {
+ queue.splice(ix, 1);
- emit('token', token);
-
- var avail = Hash(resources).filter(function (res) {
- return res.lease === null;
+ queue.forEach(function (id, j) {
+ self.sessions[id].emit('spot', j + 1, self.queue.length);
});
- if (avail.length > 0) {
- dispatch(avail.values[0], token, ms, emit);
- }
- else {
- queue.push({ token : token, time : ms, emit : emit });
- queue.forEach(function (x, i) {
- x.emit('spot', i + 1, queue.length);
- });
- self.emit('stats', self.stats());
- }
+ self.stats.waiting -= 1;
+ self.emit('stats', self.stats);
- return token;
- };
+ return;
+ }
- self.release = function (token) {
- delete tokens[token];
-
- var i = queue.map(function (q) { return q.token }).indexOf(token);
- if (i >= 0) { // in the queue
- queue.splice(i, 1);
- queue.forEach(function (x, j) {
- x.emit('spot', j + 1, queue.length);
- });
- self.emit('stats', self.stats());
- return;
- }
+ var res = hash(resources).detect(function (r) {
+ return r.lease && r.lease.token == token
+ });
+
+ if (res) { // bound to a resource
+ res.emit('release');
+ res.lease = null;
+ res.emit = null;
- var res = Hash(resources).detect(function (r) {
- return r.lease && r.lease.token == token
- });
+ self.stats.using -= 1;
- if (res) { // bound to a resource
- res.emit('release');
- res.lease = null;
- res.emit = null;
-
- self.using -= 1;
-
- var q = queue.shift();
- if (q) {
- dispatch(res, q.token, q.time, q.emit);
- queue.forEach(function (x, i) {
- x.emit('spot', i + 1, queue.length);
- });
- }
- self.emit('stats', self.stats());
+ var q = queue.shift();
+ if (q) {
+ self.dispatch(q.token, res);
+ self.queue.forEach(function (id, i) {
+ self.sessions[id].emit('spot', i + 1, self.queue.length);
+ });
}
+ self.emit('stats', self.stats);
+ }
+};
+
+Resources.prototype.dispatch = function (token, res) {
+ var self = this;
+ var session = self.sessions[token];
+
+ res.lease = {
+ start : Date.now(),
+ time : session.time,
+ token : token,
};
+ res.lease.end = res.lease.start + ms;
+ res.emit = session.emit;
- function dispatch (res, token, ms, emit) {
- res.lease = {
- start : Date.now(),
- time : ms,
- token : token,
- };
- res.lease.end = res.lease.start + ms;
- res.emit = emit;
-
- if (ms > 0) {
- setTimeout(function () {
- emit('expire');
- self.release(token);
- }, ms);
- }
-
- emit('available', res.resource, res.key, res.lease);
- self.using += 1;
- self.emit('stats', self.stats());
+ if (session.time > 0) {
+ setTimeout(function () {
+ emit('expire');
+ self.release(token);
+ }, session.time);
}
-}
+
+ session.emit('available', res.resource, res.key, res.lease);
+ self.stats.using += 1;
+ self.emit('stats', self.stats);
+};

0 comments on commit 4093f74

Please sign in to comment.