github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/ui/app/models/allocation.js (about) 1 import Ember from 'ember'; 2 import Model from 'ember-data/model'; 3 import attr from 'ember-data/attr'; 4 import { belongsTo } from 'ember-data/relationships'; 5 import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes'; 6 import PromiseObject from '../utils/classes/promise-object'; 7 import timeout from '../utils/timeout'; 8 import shortUUIDProperty from '../utils/properties/short-uuid'; 9 10 const { computed, RSVP, inject } = Ember; 11 12 const STATUS_ORDER = { 13 pending: 1, 14 running: 2, 15 complete: 3, 16 failed: 4, 17 lost: 5, 18 }; 19 20 export default Model.extend({ 21 token: inject.service(), 22 23 shortId: shortUUIDProperty('id'), 24 job: belongsTo('job'), 25 node: belongsTo('node'), 26 name: attr('string'), 27 taskGroupName: attr('string'), 28 resources: fragment('resources'), 29 modifyIndex: attr('number'), 30 modifyTime: attr('date'), 31 jobVersion: attr('number'), 32 33 // TEMPORARY: https://github.com/emberjs/data/issues/5209 34 originalJobId: attr('string'), 35 36 clientStatus: attr('string'), 37 desiredStatus: attr('string'), 38 statusIndex: computed('clientStatus', function() { 39 return STATUS_ORDER[this.get('clientStatus')] || 100; 40 }), 41 42 statusClass: computed('clientStatus', function() { 43 const classMap = { 44 pending: 'is-pending', 45 running: 'is-primary', 46 complete: 'is-complete', 47 failed: 'is-error', 48 lost: 'is-light', 49 }; 50 51 return classMap[this.get('clientStatus')] || 'is-dark'; 52 }), 53 54 taskGroup: computed('taskGroupName', 'job.taskGroups.[]', function() { 55 const taskGroups = this.get('job.taskGroups'); 56 return taskGroups && taskGroups.findBy('name', this.get('taskGroupName')); 57 }), 58 59 memoryUsed: computed.readOnly('stats.ResourceUsage.MemoryStats.RSS'), 60 cpuUsed: computed('stats.ResourceUsage.CpuStats.TotalTicks', function() { 61 return Math.floor(this.get('stats.ResourceUsage.CpuStats.TotalTicks') || 0); 62 }), 63 64 percentMemory: computed('taskGroup.reservedMemory', 'memoryUsed', function() { 65 const used = this.get('memoryUsed') / 1024 / 1024; 66 const total = this.get('taskGroup.reservedMemory'); 67 if (!total || !used) { 68 return 0; 69 } 70 return used / total; 71 }), 72 73 percentCPU: computed('cpuUsed', 'taskGroup.reservedCPU', function() { 74 const used = this.get('cpuUsed'); 75 const total = this.get('taskGroup.reservedCPU'); 76 if (!total || !used) { 77 return 0; 78 } 79 return used / total; 80 }), 81 82 stats: computed('node.{isPartial,httpAddr}', function() { 83 const nodeIsPartial = this.get('node.isPartial'); 84 85 // If the node doesn't have an httpAddr, it's a partial record. 86 // Once it reloads, this property will be dirtied and stats will load. 87 if (nodeIsPartial) { 88 return PromiseObject.create({ 89 // Never resolve, so the promise object is always in a state of pending 90 promise: new RSVP.Promise(() => {}), 91 }); 92 } 93 94 const url = `//${this.get('node.httpAddr')}/v1/client/allocation/${this.get('id')}/stats`; 95 return PromiseObject.create({ 96 promise: RSVP.Promise.race([ 97 this.get('token') 98 .authorizedRequest(url) 99 .then(res => res.json()), 100 timeout(2000), 101 ]), 102 }); 103 }), 104 105 states: fragmentArray('task-state'), 106 });