Created
June 1, 2012 06:14
-
-
Save sorear/2849465 to your computer and use it in GitHub Desktop.
ExtJS and node.js autodidacticism.
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
var AGELIMIT=120; | |
Ext.application({ | |
name: 'HelloExt', | |
launch: function() { | |
// time vs realTime is a horrible hack. time is what gets displayed, | |
// it is 0-AGELIMIT always | |
Ext.define('LoadPoint', { | |
extend: 'Ext.data.Model', | |
fields: ['load','time','realTime'] | |
}); | |
var store = Ext.create('Ext.data.Store', { | |
proxy: { | |
type: 'memory' | |
}, | |
model: 'LoadPoint' | |
}); | |
var chart = Ext.create('Ext.chart.Chart', { | |
width: 400, | |
height: 300, | |
store: store, | |
axes: [ | |
{ | |
title: 'Load', | |
type: 'Numeric', | |
position: 'left', | |
fields: ['load'], | |
minimum: 0, | |
maximum: 5 | |
}, | |
{ | |
title: 'Seconds', | |
type: 'Numeric', | |
position: 'bottom', | |
fields: ['time'], | |
minimum: 0, | |
maximum: AGELIMIT | |
} | |
], | |
series: [ | |
{ | |
type: 'line', | |
xField: 'time', | |
yField: 'load' | |
} | |
] | |
}); | |
var timeAxis = chart.axes.get(1); | |
var fetchIndex = -1; | |
var loadResults = function(obj) { | |
if (fetchIndex != obj.first) { | |
console.log('server-side connection reset'); | |
fetchIndex = obj.first; | |
store.removeAll(); | |
} | |
fetchIndex = obj.first + obj.items.length; | |
var lastTime = obj.items[obj.items.length - 1].time; | |
// server always sends us at least one item, so we always have | |
// at least one here. | |
while (store.count() != 0 && | |
lastTime - store.getAt(0).get('realTime') > AGELIMIT) { | |
store.removeAt(0); | |
} | |
//timeAxis.maximum = lastTime; | |
//timeAxis.minimum = lastTime - AGELIMIT; | |
for (var ix in obj.items) { | |
obj.items[ix].realTime = obj.items[ix].time; | |
var mis = store.add(obj.items[ix]); | |
} | |
var ct = store.count(); | |
console.log(lastTime); | |
for (var ix = 0; ix < ct; ix++) { | |
var model = store.getAt(ix); | |
model.set('time', model.get('realTime') - lastTime + AGELIMIT); | |
console.log(model.get('time')); | |
console.log(model.get('realTime')); | |
} | |
//store.loadData(obj.items, true); | |
//console.log(timeAxis); | |
console.log(chart); | |
}; | |
var fetch = function() { | |
Ext.Ajax.request({ | |
url: '/tail?from=' + fetchIndex, | |
success: function(response) { | |
loadResults(Ext.JSON.decode(response.responseText)); | |
fetch(); | |
}, | |
failure: function() { | |
// XXX set a 'Failed' banner | |
console.log('request failed'); | |
setTimeout(60000, fetch); | |
} | |
}); | |
}; | |
Ext.create('Ext.container.Viewport', { | |
layout: 'fit', | |
items: [ | |
chart | |
] | |
}); | |
fetch(); | |
} | |
}); |
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
<html> | |
<head> | |
<title>Load average thingy</title> | |
<script type="text/javascript" charset="utf-8" src="http://cdn.sencha.io/ext-4.1.0-gpl/ext-all.js"></script> | |
<link rel="stylesheet" type="text/css" href="http://cdn.sencha.io/ext-4.1.0-gpl/resources/css/ext-all.css"> | |
<script type="text/javascript" src="app.js"></script> | |
</head> | |
<body></body> | |
</html> |
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
var http = require('http'); | |
var fs = require('fs'); | |
var util = require('util'); | |
var url = require('url'); | |
var os = require('os'); | |
var POLL_MS = 2000; | |
var KEEP_VALUES = 500; | |
// state - holds the length few minutes of uptime records | |
// first, max, length, and the numeric slots are part of the public API | |
// but only for reading. | |
function MeasureBuffer(max) { | |
this.max = max; | |
this.first = 0; | |
this.length = 0; | |
this.callbacks = new Array(); | |
} | |
MeasureBuffer.prototype.slice = Array.prototype.slice; | |
MeasureBuffer.prototype.add = function (value) { | |
this[this.length++] = value; | |
if (this.length - this.first > this.max) { | |
delete this[this.first++]; | |
} | |
// snapshot callback list so that recursive adds and waits won't cause | |
// problems | |
var callbacks = this.callbacks; | |
this.callbacks = new Array(); | |
for (var cb in callbacks) { | |
callbacks[cb](); | |
} | |
}; | |
MeasureBuffer.prototype.wait = function (callback) { | |
this.callbacks.push(callback); | |
}; | |
var uptime = new MeasureBuffer(KEEP_VALUES); | |
setInterval(function () { | |
// get loadavg data, add to set, kick listeners | |
uptime.add({ time: process.uptime(), load: os.loadavg()[0] }); | |
}, POLL_MS); | |
function tail(queue, req, res, from) { | |
var respond = function () { | |
res.writeHead(200, {'Content-Type': 'application/json'}); | |
var bits = { first: from, items: queue.slice(from) }; | |
console.log(util.inspect(queue, true)); | |
console.log('-> ', JSON.stringify(bits)); | |
res.end(JSON.stringify(bits)); | |
}; | |
from = (typeof from == 'undefined') ? -1 : Number(from); | |
// strictness on queue.length is essential here to allow updating | |
if (from < queue.first || from > queue.length) { | |
// Server crash, new client, or other situation which requires | |
// a protocol reset. | |
from = queue.first; | |
} | |
if (from == queue.length) { | |
// Don't return until at least one value is available | |
queue.wait(respond); | |
} else { | |
respond(); | |
} | |
} | |
function serve_file(res, type, name) { | |
fs.readFile(name, function(err,data){ | |
res.writeHead(200, {'Content-Type': type}); | |
res.end(data); | |
}); | |
} | |
http.createServer(function (req, res) { | |
console.log('<- ', req.url); | |
var q = url.parse(req.url, true); | |
if (q.pathname == '/tail') { | |
tail(uptime, req, res, q.query.from); | |
} else if (req.url == '/app.js') { | |
serve_file(res, 'application/javascript', 'app.js'); | |
} else if (req.url == '/index.html') { | |
serve_file(res, 'text/html', 'index.html'); | |
} else { | |
res.writeHead(404, {'Content-Type': 'text/plain'}); | |
res.end('404 File Not Found\n'); | |
} | |
}).listen(1337, "127.0.0.1"); | |
console.log('Server running at http://127.0.0.1:1337/'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment