github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/components/allocation-row.js (about)

     1  import Ember from 'ember';
     2  import { inject as service } from '@ember/service';
     3  import Component from '@ember/component';
     4  import { computed } from '@ember/object';
     5  import { computed as overridable } from 'ember-overridable-computed';
     6  import { alias } from '@ember/object/computed';
     7  import { scheduleOnce } from '@ember/runloop';
     8  import { task, timeout } from 'ember-concurrency';
     9  import { lazyClick } from '../helpers/lazy-click';
    10  import AllocationStatsTracker from 'nomad-ui/utils/classes/allocation-stats-tracker';
    11  import classic from 'ember-classic-decorator';
    12  import {
    13    classNames,
    14    tagName,
    15    attributeBindings,
    16  } from '@ember-decorators/component';
    17  
    18  @classic
    19  @tagName('tr')
    20  @classNames('allocation-row', 'is-interactive')
    21  @attributeBindings(
    22    'data-test-allocation',
    23    'data-test-write-allocation',
    24    'data-test-read-allocation'
    25  )
    26  export default class AllocationRow extends Component {
    27    @service store;
    28    @service token;
    29  
    30    allocation = null;
    31  
    32    // Used to determine whether the row should mention the node or the job
    33    context = null;
    34  
    35    // Internal state
    36    statsError = false;
    37  
    38    @overridable(() => !Ember.testing) enablePolling;
    39  
    40    @computed('allocation', 'allocation.isRunning')
    41    get stats() {
    42      if (!this.get('allocation.isRunning')) return undefined;
    43  
    44      return AllocationStatsTracker.create({
    45        fetch: (url) => this.token.authorizedRequest(url),
    46        allocation: this.allocation,
    47      });
    48    }
    49  
    50    @alias('stats.cpu.lastObject') cpu;
    51    @alias('stats.memory.lastObject') memory;
    52  
    53    onClick() {}
    54  
    55    click(event) {
    56      lazyClick([this.onClick, event]);
    57    }
    58  
    59    didReceiveAttrs() {
    60      super.didReceiveAttrs();
    61      this.updateStatsTracker();
    62    }
    63  
    64    updateStatsTracker() {
    65      const allocation = this.allocation;
    66  
    67      if (allocation) {
    68        scheduleOnce('afterRender', this, qualifyAllocation);
    69      } else {
    70        this.fetchStats.cancelAll();
    71      }
    72    }
    73  
    74    @(task(function* () {
    75      do {
    76        if (this.stats) {
    77          try {
    78            yield this.get('stats.poll').linked().perform();
    79            this.set('statsError', false);
    80          } catch (error) {
    81            this.set('statsError', true);
    82          }
    83        }
    84  
    85        yield timeout(500);
    86      } while (this.enablePolling);
    87    }).drop())
    88    fetchStats;
    89  }
    90  
    91  async function qualifyAllocation() {
    92    const allocation = this.allocation;
    93  
    94    // Make sure the allocation is a complete record and not a partial so we
    95    // can show information such as preemptions and rescheduled allocation.
    96    if (allocation.isPartial) {
    97      await this.store.findRecord('allocation', allocation.id, {
    98        backgroundReload: false,
    99      });
   100    }
   101  
   102    if (allocation.get('job.isPending')) {
   103      // Make sure the job is loaded before starting the stats tracker
   104      await allocation.get('job');
   105    } else if (!allocation.get('taskGroup')) {
   106      // Make sure that the job record in the store for this allocation
   107      // is complete and not a partial from the list endpoint
   108      const job = allocation.get('job.content');
   109      if (job.isPartial) await job.reload();
   110    }
   111  
   112    this.fetchStats.perform();
   113  }