github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/ui/app/models/allocation.js (about) 1 import { inject as service } from '@ember/service'; 2 import { readOnly } from '@ember/object/computed'; 3 import { computed } from '@ember/object'; 4 import RSVP from 'rsvp'; 5 import Model from 'ember-data/model'; 6 import attr from 'ember-data/attr'; 7 import { belongsTo } from 'ember-data/relationships'; 8 import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes'; 9 import PromiseObject from '../utils/classes/promise-object'; 10 import shortUUIDProperty from '../utils/properties/short-uuid'; 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: 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: 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 = `/v1/client/allocation/${this.get('id')}/stats`; 95 return PromiseObject.create({ 96 promise: this.get('token') 97 .authorizedRequest(url) 98 .then(res => res.json()), 99 }); 100 }), 101 102 states: fragmentArray('task-state'), 103 });