Skip to content

Instantly share code, notes, and snippets.

@jajeffries
Last active August 29, 2015 14:27
Show Gist options
  • Save jajeffries/98652f2c4c2eab77df67 to your computer and use it in GitHub Desktop.
Save jajeffries/98652f2c4c2eab77df67 to your computer and use it in GitHub Desktop.
Sort of CSP channels in javascript
// 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