mirror of https://github.com/status-im/consul.git
ui: Leader API polling (#8814)
* Allow configuring a datasource to poll instead of block * Add 30 second polling to the leader API request
This commit is contained in:
parent
36d219e2cc
commit
1d324b726f
|
@ -20,9 +20,11 @@ export default Adapter.extend({
|
||||||
${{ index }}
|
${{ index }}
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
requestForQueryLeader: function(request, { dc }) {
|
requestForQueryLeader: function(request, { dc, uri }) {
|
||||||
return request`
|
return request`
|
||||||
GET /v1/status/leader?${{ dc }}
|
GET /v1/status/leader?${{ dc }}
|
||||||
|
X-Request-ID: ${uri}
|
||||||
|
Refresh: 30
|
||||||
`;
|
`;
|
||||||
},
|
},
|
||||||
queryLeader: function(store, type, id, snapshot) {
|
queryLeader: function(store, type, id, snapshot) {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { inject as service } from '@ember/service';
|
||||||
import { hash } from 'rsvp';
|
import { hash } from 'rsvp';
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
repo: service('repository/node'),
|
|
||||||
data: service('data-source/service'),
|
data: service('data-source/service'),
|
||||||
queryParams: {
|
queryParams: {
|
||||||
sortBy: 'sort',
|
sortBy: 'sort',
|
||||||
|
@ -17,7 +16,7 @@ export default Route.extend({
|
||||||
const nspace = '*';
|
const nspace = '*';
|
||||||
return hash({
|
return hash({
|
||||||
items: this.data.source(uri => uri`/${nspace}/${dc}/nodes`),
|
items: this.data.source(uri => uri`/${nspace}/${dc}/nodes`),
|
||||||
leader: this.repo.findByLeader(dc),
|
leader: this.data.source(uri => uri`/${nspace}/${dc}/leader`),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
setupController: function(controller, model) {
|
setupController: function(controller, model) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default Serializer.extend({
|
||||||
respondForQueryLeader: function(respond, query) {
|
respondForQueryLeader: function(respond, query) {
|
||||||
// don't call super here we don't care about
|
// don't call super here we don't care about
|
||||||
// ids/fingerprinting
|
// ids/fingerprinting
|
||||||
return respond(function(headers, body) {
|
return respond((headers, body) => {
|
||||||
// This response/body is just an ip:port like `"10.0.0.1:8500"`
|
// This response/body is just an ip:port like `"10.0.0.1:8500"`
|
||||||
// split it and make it look like a `C`onsul.`R`esponse
|
// split it and make it look like a `C`onsul.`R`esponse
|
||||||
// popping off the end for ports should cover us for IPv6 addresses
|
// popping off the end for ports should cover us for IPv6 addresses
|
||||||
|
@ -36,11 +36,14 @@ export default Serializer.extend({
|
||||||
const temp = body.split(':');
|
const temp = body.split(':');
|
||||||
const port = temp.pop();
|
const port = temp.pop();
|
||||||
const address = temp.join(':');
|
const address = temp.join(':');
|
||||||
// The string input `10.0.0.1:8500` would be transformed to...
|
return this.attachHeaders(
|
||||||
return {
|
headers,
|
||||||
|
{
|
||||||
Address: address,
|
Address: address,
|
||||||
Port: port,
|
Port: port,
|
||||||
};
|
},
|
||||||
|
query
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ export default Service.extend({
|
||||||
datacenters: service('repository/dc'),
|
datacenters: service('repository/dc'),
|
||||||
nodes: service('repository/node'),
|
nodes: service('repository/node'),
|
||||||
node: service('repository/node'),
|
node: service('repository/node'),
|
||||||
|
leader: service('repository/node'),
|
||||||
gateways: service('repository/service'),
|
gateways: service('repository/service'),
|
||||||
services: service('repository/service'),
|
services: service('repository/service'),
|
||||||
service: service('repository/service'),
|
service: service('repository/service'),
|
||||||
|
@ -58,6 +59,9 @@ export default Service.extend({
|
||||||
case 'policies':
|
case 'policies':
|
||||||
find = configuration => repo.findAllByDatacenter(dc, nspace, configuration);
|
find = configuration => repo.findAllByDatacenter(dc, nspace, configuration);
|
||||||
break;
|
break;
|
||||||
|
case 'leader':
|
||||||
|
find = configuration => repo.findLeader(dc, configuration);
|
||||||
|
break;
|
||||||
case 'intentions':
|
case 'intentions':
|
||||||
[method, ...slug] = rest;
|
[method, ...slug] = rest;
|
||||||
switch (method) {
|
switch (method) {
|
||||||
|
|
|
@ -5,10 +5,13 @@ export default RepositoryService.extend({
|
||||||
getModelName: function() {
|
getModelName: function() {
|
||||||
return modelName;
|
return modelName;
|
||||||
},
|
},
|
||||||
findByLeader: function(dc) {
|
findLeader: function(dc, configuration = {}) {
|
||||||
const query = {
|
const query = {
|
||||||
dc: dc,
|
dc: dc,
|
||||||
};
|
};
|
||||||
|
if (typeof configuration.refresh !== 'undefined') {
|
||||||
|
query.uri = configuration.uri;
|
||||||
|
}
|
||||||
return this.store.queryLeader(this.getModelName(), query);
|
return this.store.queryLeader(this.getModelName(), query);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -51,9 +51,13 @@ export default Store.extend({
|
||||||
// TODO: This one is only for nodes, should fail nicely if you call it
|
// TODO: This one is only for nodes, should fail nicely if you call it
|
||||||
// for anything other than nodes for good DX
|
// for anything other than nodes for good DX
|
||||||
queryLeader: function(modelName, query) {
|
queryLeader: function(modelName, query) {
|
||||||
// TODO: no normalization, type it properly for the moment
|
|
||||||
const adapter = this.adapterFor(modelName);
|
const adapter = this.adapterFor(modelName);
|
||||||
return adapter.queryLeader(this, { modelName: modelName }, null, query);
|
const serializer = this.serializerFor(modelName);
|
||||||
|
const modelClass = { modelName: modelName };
|
||||||
|
return adapter.queryLeader(this, modelClass, null, query).then(payload => {
|
||||||
|
payload.meta = serializer.normalizeMeta(this, modelClass, payload, null, 'leader');
|
||||||
|
return payload;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// TODO: This one is only for nspaces and OIDC, should fail nicely if you call it
|
// TODO: This one is only for nspaces and OIDC, should fail nicely if you call it
|
||||||
// for anything other than nspaces/OIDC for good DX
|
// for anything other than nspaces/OIDC for good DX
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{{title 'Nodes'}}
|
{{title 'Nodes'}}
|
||||||
<EventSource @src={{items}} />
|
<EventSource @src={{items}} />
|
||||||
|
<EventSource @src={{leader}} />
|
||||||
{{#let (hash
|
{{#let (hash
|
||||||
statuses=(if status (split status ',') undefined)
|
statuses=(if status (split status ',') undefined)
|
||||||
) as |filters|}}
|
) as |filters|}}
|
||||||
|
|
|
@ -36,9 +36,9 @@ module('Integration | Adapter | node', function(hooks) {
|
||||||
const adapter = this.owner.lookup('adapter:node');
|
const adapter = this.owner.lookup('adapter:node');
|
||||||
const client = this.owner.lookup('service:client/http');
|
const client = this.owner.lookup('service:client/http');
|
||||||
const expected = `GET /v1/status/leader?dc=${dc}`;
|
const expected = `GET /v1/status/leader?dc=${dc}`;
|
||||||
const actual = adapter.requestForQueryLeader(client.url, {
|
const actual = adapter.requestForQueryLeader(client.requestParams.bind(client), {
|
||||||
dc: dc,
|
dc: dc,
|
||||||
});
|
});
|
||||||
assert.equal(actual, expected);
|
assert.equal(`${actual.method} ${actual.url}`, expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -80,6 +80,10 @@ module('Integration | Serializer | node', function(hooks) {
|
||||||
const expected = {
|
const expected = {
|
||||||
Address: '211.245.86.75',
|
Address: '211.245.86.75',
|
||||||
Port: '8500',
|
Port: '8500',
|
||||||
|
[META]: {
|
||||||
|
[DC.toLowerCase()]: dc,
|
||||||
|
[NSPACE.toLowerCase()]: nspace,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const actual = serializer.respondForQueryLeader(
|
const actual = serializer.respondForQueryLeader(
|
||||||
function(cb) {
|
function(cb) {
|
||||||
|
|
Loading…
Reference in New Issue