Skip to content

Instantly share code, notes, and snippets.

@wheeyls
Last active December 19, 2015 11:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wheeyls/5945470 to your computer and use it in GitHub Desktop.
Save wheeyls/5945470 to your computer and use it in GitHub Desktop.
Queue Example for my blog
function logEvent(eventData) {
$.ajax({
method: 'post',
url: '/analytics-endpoint',
data: eventData
});
}
function readFromStorage(key) {
var listString = window.localStorage.getItem(key)
, list = listString && JSON.parse(listString)
;
return list;
}
function writeToStorage(key, obj) {
window.localStorage.setItem(key, obj);
}
function persistentQueue(name) {
var prefix = 'persistentQueue:'
, q
, key = prefix + name
;
q = queue(readFromStorage(key));
q.onEnqueue = q.onDequeue = function (list) {
writeToStorage(key, list);
};
return q;
}
function queueManager(myQueue, callback) {
//...
function fail(message) {
failCount += 1;
me.onFail(myQueue.peek(), failCount);
// try again
process();
}
function flush() {
if (!flushing) {
flushing = true;
process();
}
}
function next() {
failCount = 0;
myQueue.dequeue();
me.onNext(myQueue.peek());
process();
}
function process() {
if (myQueue.hasAny()) {
callback(myQueue.peek(), next, fail);
} else {
// done
flushing = false;
me.onFlush();
}
}
return me = {
flush: flush
// hooks
, onFail: function (item, count) { }
, onNext: function (item) { }
, onFlush: function () { }
};
// start flushing whenever item is added to queue
(function () {
var old = myQueue.onEnqueue;
myQueue.onEnqueue = function (list) {
old(list);
flush();
};
}());
var analyticsEvents = queue()
, qm;
qm = queueManager(analyticsEvents, function (eventData, next, fail) {
$.ajax({
method: 'post',
url: '/analytics-endpoint',
data: eventData,
success: next,
error: fail
});
});
function logEvent(eventData) {
analyticsEvents.enqueue(eventData);
}
var q = queue()
, qm
, counter = 0
;
qm = queueManager(q, function (item, next, fail) {
// fail every other try
counter += 1
if (counter % 2 === 1) {
console.log('Retrying ' + item);
fail();
} else {
console.log(item + ' processed successfully.')
next();
}
});
q.enqueue('item1', 'item2');
// output:
// Retrying item1
// item1 processed successfully.
// Retrying item2
// item2 processed successfully.
function queueManager(myQueue, callback) {
var flushing = false
, me
, failCount = 0
;
function flush() {
if (!flushing) {
flushing = true;
process();
}
}
function process() {
if (myQueue.hasAny()) {
callback(myQueue.peek(), next, fail);
} else {
// done
flushing = false;
me.onFlush();
}
}
function next() {
failCount = 0;
myQueue.dequeue();
me.onNext(myQueue.peek());
process();
}
function fail(message) {
failCount += 1;
me.onFail(myQueue.peek(), failCount);
// try again
process();
}
// start flushing whenever item is added to queue
(function () {
var old = myQueue.onEnqueue;
myQueue.onEnqueue = function (list) {
old(list);
flush();
};
}());
return me = {
flush: flush
// hooks
, onFail: function (item, count) { }
, onNext: function (item) { }
, onFlush: function () { }
};
}
var myQueue = queue();
// use the hooks to print status to the console
myQueue.onEnqueue = function (list) { console.log(list); }
myQueue.onDequeue = function (list) { console.log(list); }
queue.hasAny(); // false
// call enqueue to add values
queue.enqueue(1);
// [1]
queue.enqueue(2, 3);
// [1, 2, 3]
queue.hasAny(); // true
// call dequeue to remove values
var item = queue.dequeue();
// [2, 3]
console.log(item); // 1
// call peek to view an item without removing it
item = queue.peek();
console.log(item); // 2
queue.all(); // [2, 3]
function queue(list) {
var me;
list = list || [];
return me = {
enqueue: function () {
var args = Array.prototype.slice.call(arguments)
, i, ii
;
for (i = 0, ii = args.length; i < ii; i++) {
list.push(args[i]);
}
me.onEnqueue(me.all());
}
, dequeue: function (callback) {
var value = list.shift();
me.onDequeue(me.all());
return value;
}
, peek: function () {
return list[0];
}
, all: function () {
// return a copy of the list
return list.slice(0);
}
, hasAny: function () {
return list.length > 0;
}
// hooks
, onEnqueue: function (list) { }
, onDequeue: function (list) { }
};
}
var analyticsEvents = persistentQueue('analytics')
, qm;
qm = queueManager(analyticsEvents, function (eventData, next, fail) {
$.ajax({
method: 'post',
url: '/analytics-endpoint',
data: eventData,
success: next,
error: fail
});
});
function logEvent(eventData) {
analyticsEvents.enqueue(eventData);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment