Skip to content
Snippets Groups Projects
Commit 64d66c80 authored by Mathis Neumann's avatar Mathis Neumann
Browse files

reload data if revision check failed

parent a6610851
No related branches found
No related tags found
No related merge requests found
...@@ -12,7 +12,7 @@ export default BaseAdapter.extend(UrlTemplates, { ...@@ -12,7 +12,7 @@ export default BaseAdapter.extend(UrlTemplates, {
urlSegments: { urlSegments: {
systemId() { systemId() {
return this.get('session.systemId'); return this.get('session.system.id');
} }
} }
}); });
\ No newline at end of file
...@@ -4,5 +4,8 @@ import attr from 'ember-data/attr'; ...@@ -4,5 +4,8 @@ import attr from 'ember-data/attr';
export default Model.extend({ export default Model.extend({
// id: attr('string') - not allowed to be listed by ember // id: attr('string') - not allowed to be listed by ember
systemId: attr('string'), systemId: attr('string'),
type: attr('string') type: attr('string'),
revisionNumber: attr('number'),
changelogSequence: attr('number'),
lastUpdate: attr('date')
}); });
import BaseEntity from './baseentity';
import attr from 'ember-data/attr';
const Model = BaseEntity.extend({
technology: attr('string'),
sourceId: attr('string'),
targetId: attr('string'),
workload: attr('number')
});
export default Model;
\ No newline at end of file
import BaseEntity from './baseentity'; import BaseEntity from './baseentity';
import attr from 'ember-data/attr'; import attr from 'ember-data/attr';
import { memberAction } from 'ember-api-actions';
const Model = BaseEntity.extend({ const Model = BaseEntity.extend({
name: attr('string') name: attr('string'),
getRevision: memberAction({ path: 'revision', type: 'GET', urlType: 'findRecord'})
}); });
Model.reopenClass({ Model.reopenClass({
......
...@@ -5,9 +5,7 @@ export default Ember.Route.extend({ ...@@ -5,9 +5,7 @@ export default Ember.Route.extend({
changelogStream: Ember.inject.service(), changelogStream: Ember.inject.service(),
model(params) { model(params) {
const systemId = params.systemId; const systemId = params.systemId;
this.set('session.systemId', systemId); // add the system to all requests
const changelogStream = this.get('changelogStream'); // lazy loaded, requires session id
changelogStream.connect(systemId);
/* /*
* note that findAll returns an Observable Array which automatically * note that findAll returns an Observable Array which automatically
...@@ -19,8 +17,47 @@ export default Ember.Route.extend({ ...@@ -19,8 +17,47 @@ export default Ember.Route.extend({
* We also load all the data, so that the transformation strategies can assume that the whole * We also load all the data, so that the transformation strategies can assume that the whole
* meta model is cached. This also allowes that the architecture view is only an alias * meta model is cached. This also allowes that the architecture view is only an alias
*/ */
return this.loadSystem(systemId)
.then(this.loadRevision.bind(this))
.then((revision) => {
return Ember.RSVP.resolve()
.then(this.loadMetaModel.bind(this))
.then(models => this.verifyRevision(revision, models))
.then((models) => {
this.debug('loaded models', models);
return {
systemId: systemId,
revision: revision,
instances: models,
mode: this.get('routeName').split('.')[0] // deployments/architectures
};
});
})
.catch(err => {
if(err === 'outdated') {
// wait a bit to avoid DDOS, TODO: exponential backoff?
this.refresh();
} else {
console.error('could not load models', err);
}
throw err; // TODO: handle errors in UI
});
},
loadSystem(systemId) {
return this.store.findRecord('system', systemId)
.then((system) => {
this.debug('loaded system', system);
this.set('session.system', system); // add the system to all requests
const changelogStream = this.get('changelogStream'); // lazy loaded, requires session id
changelogStream.connect(system.id);
return system;
});
},
loadRevision(system) {
return system.getRevision();
},
loadMetaModel(system) {
const load = (type) => this.store.findAll(type); const load = (type) => this.store.findAll(type);
return Ember.RSVP.hash({ return Ember.RSVP.hash({
nodes: load('node'), nodes: load('node'),
nodeGroups: load('nodegroup'), nodeGroups: load('nodegroup'),
...@@ -28,16 +65,25 @@ export default Ember.Route.extend({ ...@@ -28,16 +65,25 @@ export default Ember.Route.extend({
serviceInstances: load('serviceinstance'), serviceInstances: load('serviceinstance'),
communications: load('communication'), communications: load('communication'),
communicationInstances: load('communicationinstance') communicationInstances: load('communicationinstance')
}).then((models) => {
this.debug('loaded models', models);
return {
systemId: systemId,
instances: models,
mode: this.get('routeName').split('.')[0]
};
}); });
}, },
verifyRevision(revision, models) {
const outdatedRecords = Object
.keys(models)
.map(key => models[key])
.filter(instances => {
return instances.filter(record =>
record.get('revisionNumber') >= revision.revisionNumber && record.get('changelogSequence') > revision.changelogSequence
).length > 0;
});
if(outdatedRecords.length > 0) {
this.debug('records loaded from server seem to have changed during loading, refreshing data!', revision, models);
return Ember.RSVP.Promise.reject('outdated');
}
return models;
},
actions: { actions: {
loadDetails(rawEntity) { loadDetails(rawEntity) {
this.debug('loadDetails action', rawEntity); this.debug('loadDetails action', rawEntity);
...@@ -63,6 +109,7 @@ export default Ember.Route.extend({ ...@@ -63,6 +109,7 @@ export default Ember.Route.extend({
// do not disconnect if transitioning to a child route (details) // do not disconnect if transitioning to a child route (details)
if (transition.targetName.indexOf(this.get('routeName')) !== 0) { if (transition.targetName.indexOf(this.get('routeName')) !== 0) {
this.get('changelogStream').disconnect(); this.get('changelogStream').disconnect();
clearTimeout(this.get('refreshTimeout'));
} }
} }
} }
......
...@@ -9,6 +9,11 @@ export default Ember.Service.extend({ ...@@ -9,6 +9,11 @@ export default Ember.Service.extend({
this.debug('session', this.get('systemId')); this.debug('session', this.get('systemId'));
}, },
connect(systemId) { connect(systemId) {
if(this.get('socket')) {
this.debug('already connected, disconnecting first');
this.disconnect();
}
this.set('shouldClose', false); this.set('shouldClose', false);
this.debug('setting up websocket', systemId); this.debug('setting up websocket', systemId);
...@@ -40,6 +45,7 @@ export default Ember.Service.extend({ ...@@ -40,6 +45,7 @@ export default Ember.Service.extend({
this.debug('disconnect'); this.debug('disconnect');
this.set('shouldClose', true); this.set('shouldClose', true);
this.get('socket').close(); this.get('socket').close();
this.set('socket', null);
// just in case it disconnected right before disconnect() was called. // just in case it disconnected right before disconnect() was called.
clearTimeout(this.get('reconnectionTimeout')); clearTimeout(this.get('reconnectionTimeout'));
......
...@@ -8,10 +8,10 @@ import Ember from 'ember'; ...@@ -8,10 +8,10 @@ import Ember from 'ember';
* @public * @public
*/ */
export default Ember.Service.extend({ export default Ember.Service.extend({
/** systemId store the id of the system which is currently used for /** system stores the system which is currently used for
* loading metamodel components * loading metamodel components
* @type {String} * @type {System}
* @property systemId * @property system
*/ */
systemId: null system: null
}); });
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"devDependencies": { "devDependencies": {
"broccoli-asset-rev": "^2.2.0", "broccoli-asset-rev": "^2.2.0",
"ember-ajax": "0.7.1", "ember-ajax": "0.7.1",
"ember-api-actions": "0.1.6",
"ember-browserify": "^1.1.8", "ember-browserify": "^1.1.8",
"ember-cli": "2.4.2", "ember-cli": "2.4.2",
"ember-cli-app-version": "^1.0.0", "ember-cli-app-version": "^1.0.0",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment