Skip to content

Commit

Permalink
dont store historical data for eternity in the same precision
Browse files Browse the repository at this point in the history
  • Loading branch information
selaux committed Mar 19, 2014
1 parent 5d52d71 commit 99ba2b7
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 4 deletions.
50 changes: 46 additions & 4 deletions lib/modules/miners/bfgminer.js
Expand Up @@ -15,7 +15,9 @@ module.exports = Module.extend({
defaults: {
host: '127.0.0.1',
port: 4028,
interval: 1000
interval: 1000,
historicalDataStoredFor: 24 * 60 * 60 * 1000,
historicalDataPrecision: 15 * 60 * 1000
},

viewId: 'miner',
Expand All @@ -34,6 +36,7 @@ module.exports = Module.extend({
reportError = function (err) {
self.set(_.extend({}, defaults, {
connected: false,
avgHashrate: 0,
error: err.toString()
}));
};
Expand Down Expand Up @@ -231,17 +234,56 @@ module.exports = Module.extend({
},

set: function () {
var attributes = arguments[0],
historicalData = this.get('historicalData') || [];
var self = this,
attributes = arguments[0],
historicalData = this.get('historicalData') || [],
now = new Date().getTime();

historicalData.push({ timestamp: new Date().getTime(), avgHashrate: attributes.avgHashrate });
historicalData = historicalData.filter(function (observation) {
return observation.timestamp > (now - self.config.historicalDataStoredFor);
});
historicalData.push({ timestamp: now, avgHashrate: attributes.avgHashrate, aggregated: false });
historicalData = this.aggregateValues(historicalData);

attributes.historicalData = historicalData;
arguments[0] = attributes;

Module.prototype.set.apply(this, arguments);
},

aggregateValues: function (historicalData) {
var self = this,
firstNonAggregatedIndex = _.findIndex(historicalData, function (ob) {
return !ob.aggregated;
}),
aggregatedData = historicalData.slice(0, firstNonAggregatedIndex),
nonAggregatedData = historicalData.slice(firstNonAggregatedIndex),
aggregationPossible = nonAggregatedData.length > 1,
modeIndex = Math.ceil(nonAggregatedData.length / 2),
modeObservation = nonAggregatedData[modeIndex],
arrayToAggregate,
aggregateValue;

if (aggregationPossible && modeObservation.timestamp - nonAggregatedData[0].timestamp >= self.config.historicalDataPrecision) {
arrayToAggregate = nonAggregatedData.slice(0, modeIndex+1);
nonAggregatedData = nonAggregatedData.slice(modeIndex+1);

aggregateValue = _.reduce(arrayToAggregate, function (memo, ob) {
return _.extend(memo, {
timestamp: memo.timestamp + (ob.timestamp / arrayToAggregate.length),
avgHashrate: memo.avgHashrate + (ob.avgHashrate / arrayToAggregate.length)
});
}, {
timestamp: 0,
avgHashrate: 0,
aggregated: true
});
aggregatedData.push(aggregateValue);
}

return aggregatedData.concat(nonAggregatedData);
},

getViewData: function () {
return this.data.connected ? this.data : {};
}
Expand Down
66 changes: 66 additions & 0 deletions test/specs/lib/modules/miners/bfgminerSpec.js
Expand Up @@ -133,6 +133,7 @@ describe('modules/miners/bfgminer', function () {

expect(data).to.deep.equal({
connected: false,
avgHashrate: 0,
error: 'Error: Test Error'
});
done();
Expand Down Expand Up @@ -544,6 +545,71 @@ describe('modules/miners/bfgminer', function () {
expect(bfgAdapter.get('historicalData')[1].avgHashrate).to.equal(789);
expect(bfgAdapter.get('historicalData')[1].timestamp).to.be.within(now-1, now+1);
});

it('should remove historical data that has been logged longer than the expiration date', function () {
var bfgAdapter = new BfgAdapter({}, _.defaults({ historicalDataStoredFor: 5000 }, config)),
now = new Date().getTime();

bfgAdapter.attributes.historicalData = [
{ timestamp: now-5100, avgHashrate: 456 },
{ timestamp: now-2500, avgHashrate: 456 }
];
bfgAdapter.set({ avgHashrate: 789 });
expect(bfgAdapter.get('historicalData')).to.have.length(2);
expect(bfgAdapter.get('historicalData')[0]).to.deep.equal({ timestamp: now-2500, avgHashrate: 456 });
expect(bfgAdapter.get('historicalData')[1].avgHashrate).to.equal(789);
expect(bfgAdapter.get('historicalData')[1].timestamp).to.be.within(now-1, now+1);
});
});

describe('aggregateValues', function () {
it('should aggregate data if the time between first non-aggregated value and the mode is larger than the historicalDataPrecision', function () {
var bfgAdapter = new BfgAdapter({}, _.defaults({ historicalDataPrecision: 4, historicalDataStoredFor: Infinity }, config)),
aggregated;

aggregated = bfgAdapter.aggregateValues([
{ timestamp: 1, avgHashrate: 2, aggregated: false },
{ timestamp: 2, avgHashrate: 4, aggregated: false },
{ timestamp: 3, avgHashrate: 2, aggregated: false },
{ timestamp: 4, avgHashrate: 4, aggregated: false },
{ timestamp: 5, avgHashrate: 2, aggregated: false },
{ timestamp: 6, avgHashrate: 4, aggregated: false },
{ timestamp: 7, avgHashrate: 2, aggregated: false },
{ timestamp: 8, avgHashrate: 4, aggregated: false },
{ timestamp: 9, avgHashrate: 2, aggregated: false },
{ timestamp: 10, avgHashrate: 4, aggregated: false }
]);
expect(aggregated).to.have.length(5);
expect(aggregated[0]).to.deep.equal({ timestamp: 21/6, avgHashrate: 3, aggregated: true });
expect(aggregated[1]).to.deep.equal({ timestamp: 7, avgHashrate: 2, aggregated: false });
expect(aggregated[2]).to.deep.equal({ timestamp: 8, avgHashrate: 4, aggregated: false });
expect(aggregated[3]).to.deep.equal({ timestamp: 9, avgHashrate: 2, aggregated: false });
expect(aggregated[4]).to.deep.equal({ timestamp: 10, avgHashrate: 4, aggregated: false });
});

it('should aggregate data if the time between the current measurement and the first measurement is larger than twice the historicalDataPrecision', function () {
var bfgAdapter = new BfgAdapter({}, _.defaults({ historicalDataPrecision: 4, historicalDataStoredFor: Infinity }, config)),
aggregated;

aggregated = bfgAdapter.aggregateValues([
{ timestamp: 1, avgHashrate: 3, aggregated: true },
{ timestamp: 2, avgHashrate: 4, aggregated: false },
{ timestamp: 3, avgHashrate: 2, aggregated: false },
{ timestamp: 4, avgHashrate: 4, aggregated: false },
{ timestamp: 5, avgHashrate: 2, aggregated: false },
{ timestamp: 6, avgHashrate: 4, aggregated: false },
{ timestamp: 7, avgHashrate: 2, aggregated: false },
{ timestamp: 8, avgHashrate: 4, aggregated: false },
{ timestamp: 9, avgHashrate: 2, aggregated: false }
]);

expect(aggregated).to.have.length(5);
expect(aggregated[0]).to.deep.equal({ timestamp: 1, avgHashrate: 3, aggregated: true });
expect(aggregated[1]).to.deep.equal({ timestamp: 20 / 5, avgHashrate: 16 / 5, aggregated: true });
expect(aggregated[2]).to.deep.equal({ timestamp: 7, avgHashrate: 2, aggregated: false });
expect(aggregated[3]).to.deep.equal({ timestamp: 8, avgHashrate: 4, aggregated: false });
expect(aggregated[4]).to.deep.equal({ timestamp: 9, avgHashrate: 2, aggregated: false });
});
});

});

0 comments on commit 99ba2b7

Please sign in to comment.