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:
John Cowen 2020-10-06 14:26:44 +01:00 committed by GitHub
parent 36d219e2cc
commit 1d324b726f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 34 additions and 14 deletions

View File

@ -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) {

View File

@ -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) {

View File

@ -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, {
Port: port, Address: address,
}; Port: port,
},
query
);
}); });
}, },
}); });

View File

@ -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) {

View File

@ -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);
}, },
}); });

View File

@ -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

View File

@ -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|}}

View File

@ -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);
}); });
}); });

View File

@ -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) {