Last active
August 29, 2015 14:27
-
-
Save jajeffries/98652f2c4c2eab77df67 to your computer and use it in GitHub Desktop.
Sort of CSP channels in javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// channels.js is free software: you can redistribute it and/or modify | |
// it under the terms of the GNU General Public License as published by | |
// the Free Software Foundation, either version 3 of the License, or | |
// (at your option) any later version. | |
// channels.js is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// You should have received a copy of the GNU General Public License | |
// along with channels.js. If not, see <http://www.gnu.org/licenses/>. | |
function chan(bufferSize) { | |
return new Channel(bufferSize || 1); | |
} | |
function go(routine) { | |
setTimeout(routine, 0); | |
} | |
function Channel(bufferSize) { | |
var _state = { | |
OPEN: "OPEN", | |
CLOSED: "CLOSED" | |
}; | |
var self = this, | |
currentState = _state.OPEN, | |
buffer = [], | |
interval; | |
self.put = function (value) { | |
buffer.push(value); | |
if(buffer.length > bufferSize) { | |
buffer.splice(0, buffer.length - bufferSize); | |
} | |
}; | |
self.take = function (callback) { | |
if(currentState === _state.OPEN) { | |
interval = setTimeout(function () { | |
if(buffer.length === 0) { | |
clearInterval(interval); | |
return self.take(callback); | |
} else { | |
return callback(buffer.shift()); | |
} | |
}, 50); | |
} else { | |
return callback(null); | |
} | |
}; | |
self.close = function () { | |
clearTimeout(interval); | |
currentState = _state.CLOSED; | |
}; | |
} | |
// Basic example | |
var channel = chan(); | |
go(function () { | |
channel.put("Hello"); | |
}); | |
go(function () { | |
channel.take(function(value) { | |
console.log("My value from the channel", value); | |
}); | |
}); | |
// Clsoing a channel | |
var closingAChannel = chan(); | |
go(closingAChannel.close); | |
go(function () { | |
closingAChannel.take(function(value) { | |
console.log("Take on a closed channel returns null!", value); | |
}); | |
}); | |
// Setting the size of the channels buffer | |
var bufferedChannel = chan(2); | |
go(function () { | |
bufferedChannel.put("This will get pushed out of the buffer"); | |
bufferedChannel.put("Hello again"); | |
bufferedChannel.put("Hello again again!"); | |
}); | |
go(function () { | |
bufferedChannel.take(function(value) { | |
console.log("Buffered so only 2 values", value); | |
}); | |
bufferedChannel.take(function(value) { | |
console.log("Buffered so only 2 values", value); | |
}); | |
}); | |
// Show that taking frmo a channel blocks until something is put on the channel | |
var blockingChannel = chan(); | |
go(function () { | |
blockingChannel.take(function(value) { | |
console.log("This was blocking until something was send to the channel", value); | |
}); | |
}); | |
setTimeout(function () { | |
go(function () { | |
blockingChannel.put("Hello from a queue that was blocking!"); | |
}); | |
}, 2000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment