import { next } from '@ember/runloop'; import { alias } from '@ember/object/computed'; import Component from '@ember/component'; import MultiStatsSocket from 'ui/utils/multi-stats'; import layout from './template'; const FIELDS = ['cpuUser','cpuSystem','cpuTotal','networkTx','networkRx','networkTotal','memory','storageWrite','storageRead','storageTotal']; export default Component.extend({ layout, model: null, linkName: 'containerStats', maxPoints: 60, emitInterval: 1000, emitMaps: false, available: alias('statsSocket.available'), active: alias('statsSocket.active'), loading: alias('statsSocket.loading'), tagName: '', statsSocket: null, emitTimer: null, init() { this._super(...arguments); this.set('boundEmit', this.emit.bind(this)); }, didReceiveAttrs() { this._super(...arguments); if ( this.get('statsSocket') ) { this.disconnect(); this.tearDown(); } this.connect(); }, willDestroyElement: function() { this._super(...arguments); this.disconnect(); this.tearDown(); }, onActiveChanged: function() { if ( this.isDestroyed || this.isDestroying ) { return; } if ( !this.get('active') ) { this.tearDown(); } }.observes('active'), connect() { next(() => { try { var stats = MultiStatsSocket.create({ resource: this.get('model'), linkName: this.get('linkName'), }); this.set('statsSocket',stats); stats.on('dataPoint', (data) => { this.onDataPoint(data); }); } catch(e) { } }); }, disconnect() { var stats = this.get('statsSocket'); if ( stats ) { stats.close(); } }, setUp() { FIELDS.forEach((field) => { let data = []; this.set(field, data); this.set(field+'_A', {}); this.set(field+'_B', {}); }); if ( this.get('emitMaps') ) { let mapAry = []; this.set('maps', mapAry); } this.startTimer(); }, tearDown() { this.stopTimer(); this.set('maps', null); FIELDS.forEach((field) => { this.set(field, null); this.set(field+'_A', null); this.set(field+'_B', null); }); }, startTimer() { this.stopTimer(); this.set('emitTimer', setInterval(this.get('boundEmit'), this.get('emitInterval'))); }, stopTimer() { clearInterval(this.get('emitTimer')); }, onDataPoint(point) { if ( this.isDestroyed || this.isDestroying ) { return; } if ( !this.get('cpuSystem_A') ) { this.setUp(); } let key = point.key; this.get('cpuSystem_A')[key] = point.cpu_system || 0; this.get('cpuUser_A')[key] = point.cpu_user || 0; this.get('cpuTotal_A')[key] = point.cpu_total || 0; this.get('memory_A')[key] = point.mem_used_mb || 0; this.get('networkTx_A')[key] = point.net_tx_kb*8 || 0; this.get('networkRx_A')[key] = point.net_rx_kb*8 || 0; this.get('networkTotal_A')[key] = this.get('networkTx_A')[key] + this.get('networkRx_A')[key]; this.get('storageWrite_A')[key] = point.disk_write_kb*8 || 0; this.get('storageRead_A')[key] = point.disk_read_kb*8 || 0; this.get('storageTotal_A')[key] = this.get('storageWrite_A')[key] + this.get('storageRead_A')[key]; }, emit() { let ary, field, valueMapA, valueMapB, keys, sum; let maxPoints = this.get('maxPoints'); let map = {}; let emitMaps = this.get('emitMaps'); for ( let i = 0 ; i < FIELDS.length ; i++ ) { field = FIELDS[i]; // Average out the last 2 points from each field. valueMapA = this.get(field+'_A'); valueMapB = this.get(field+'_B'); this.set(field+'_B',valueMapA); this.set(field+'_A',{}); ary = this.get(field); sum = 0; field = FIELDS[i]; keys = Object.keys(valueMapA); for ( let j = 0 ; j < keys.length ; j++ ) { sum += valueMapA[keys[j]]; } keys = Object.keys(valueMapB); if ( keys && keys.length ) { for ( let j = 0 ; j < keys.length ; j++ ) { sum += valueMapB[keys[j]]; } sum = Math.round(sum/2); } while ( ary.get('length') >= maxPoints ) { ary.removeAt(0); } ary.pushObject(sum); if ( emitMaps ) { map[field] = sum; } } if ( emitMaps ) { let mapAry = this.get('maps'); while ( mapAry.get('length') >= maxPoints ) { mapAry.removeAt(0); } mapAry.push(map); } }, });