github.com/emate/nomad@v0.8.2-wo-binpacking/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 { run } from '@ember/runloop';
     6  import { lazyClick } from '../helpers/lazy-click';
     7  import { task, timeout } from 'ember-concurrency';
     8  
     9  export default Component.extend({
    10    store: service(),
    11  
    12    tagName: 'tr',
    13  
    14    classNames: ['allocation-row', 'is-interactive'],
    15  
    16    allocation: null,
    17  
    18    // Used to determine whether the row should mention the node or the job
    19    context: null,
    20  
    21    backoffSequence: computed(() => [500, 800, 1300, 2100, 3400, 5500]),
    22  
    23    // Internal state
    24    stats: null,
    25    statsError: false,
    26  
    27    enablePolling: computed(() => !Ember.testing),
    28  
    29    onClick() {},
    30  
    31    click(event) {
    32      lazyClick([this.get('onClick'), event]);
    33    },
    34  
    35    didReceiveAttrs() {
    36      // TODO: Use this code again once the temporary workaround below
    37      // is resolved.
    38  
    39      // If the job for this allocation is incomplete, reload it to get
    40      // detailed information.
    41      // const allocation = this.get('allocation');
    42      // if (
    43      //   allocation &&
    44      //   allocation.get('job') &&
    45      //   !allocation.get('job.isPending') &&
    46      //   !allocation.get('taskGroup')
    47      // ) {
    48      //   const job = allocation.get('job.content');
    49      //   job && job.reload();
    50      // }
    51  
    52      // TEMPORARY: https://github.com/emberjs/data/issues/5209
    53      // Ember Data doesn't like it when relationships aren't reflective,
    54      // which means the allocation's job will be null if it hasn't been
    55      // resolved through the allocation (allocation.get('job')) before
    56      // being resolved through the store (store.findAll('job')). The
    57      // workaround is to persist the jobID as a string on the allocation
    58      // and manually re-link the two records here.
    59      const allocation = this.get('allocation');
    60  
    61      if (allocation) {
    62        this.get('fetchStats').perform(allocation);
    63      } else {
    64        this.get('fetchStats').cancelAll();
    65        this.set('stats', null);
    66      }
    67      run.scheduleOnce('afterRender', this, qualifyJob);
    68    },
    69  
    70    fetchStats: task(function*(allocation) {
    71      const backoffSequence = this.get('backoffSequence').slice();
    72      const maxTiming = backoffSequence.pop();
    73  
    74      do {
    75        try {
    76          const stats = yield allocation.fetchStats();
    77          this.set('stats', stats);
    78          this.set('statsError', false);
    79        } catch (error) {
    80          this.set('statsError', true);
    81        }
    82        yield timeout(backoffSequence.shift() || maxTiming);
    83      } while (this.get('enablePolling'));
    84    }).drop(),
    85  });
    86  
    87  function qualifyJob() {
    88    const allocation = this.get('allocation');
    89    if (allocation.get('originalJobId')) {
    90      const job = this.get('store').peekRecord('job', allocation.get('originalJobId'));
    91      if (job) {
    92        allocation.setProperties({
    93          job,
    94          originalJobId: null,
    95        });
    96        if (job.get('isPartial')) {
    97          job.reload();
    98        }
    99      } else {
   100        this.get('store')
   101          .findRecord('job', allocation.get('originalJobId'))
   102          .then(job => {
   103            allocation.set('job', job);
   104          });
   105      }
   106    }
   107  }