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 }}
`;
},
requestForQueryLeader: function(request, { dc }) {
requestForQueryLeader: function(request, { dc, uri }) {
return request`
GET /v1/status/leader?${{ dc }}
X-Request-ID: ${uri}
Refresh: 30
`;
},
queryLeader: function(store, type, id, snapshot) {

View File

@ -3,7 +3,6 @@ import { inject as service } from '@ember/service';
import { hash } from 'rsvp';
export default Route.extend({
repo: service('repository/node'),
data: service('data-source/service'),
queryParams: {
sortBy: 'sort',
@ -17,7 +16,7 @@ export default Route.extend({
const nspace = '*';
return hash({
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) {

View File

@ -28,7 +28,7 @@ export default Serializer.extend({
respondForQueryLeader: function(respond, query) {
// don't call super here we don't care about
// 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"`
// split it and make it look like a `C`onsul.`R`esponse
// 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 port = temp.pop();
const address = temp.join(':');
// The string input `10.0.0.1:8500` would be transformed to...
return {
Address: address,
Port: port,
};
return this.attachHeaders(
headers,
{
Address: address,
Port: port,
},
query
);
});
},
});

View File

@ -5,6 +5,7 @@ export default Service.extend({
datacenters: service('repository/dc'),
nodes: service('repository/node'),
node: service('repository/node'),
leader: service('repository/node'),
gateways: service('repository/service'),
services: service('repository/service'),
service: service('repository/service'),
@ -58,6 +59,9 @@ export default Service.extend({
case 'policies':
find = configuration => repo.findAllByDatacenter(dc, nspace, configuration);
break;
case 'leader':
find = configuration => repo.findLeader(dc, configuration);
break;
case 'intentions':
[method, ...slug] = rest;
switch (method) {

View File

@ -5,10 +5,13 @@ export default RepositoryService.extend({
getModelName: function() {
return modelName;
},
findByLeader: function(dc) {
findLeader: function(dc, configuration = {}) {
const query = {
dc: dc,
};
if (typeof configuration.refresh !== 'undefined') {
query.uri = configuration.uri;
}
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
// for anything other than nodes for good DX
queryLeader: function(modelName, query) {
// TODO: no normalization, type it properly for the moment
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
// for anything other than nspaces/OIDC for good DX

View File

@ -1,5 +1,6 @@
{{title 'Nodes'}}
<EventSource @src={{items}} />
<EventSource @src={{leader}} />
{{#let (hash
statuses=(if status (split status ',') undefined)
) as |filters|}}

View File

@ -36,9 +36,9 @@ module('Integration | Adapter | node', function(hooks) {
const adapter = this.owner.lookup('adapter:node');
const client = this.owner.lookup('service:client/http');
const expected = `GET /v1/status/leader?dc=${dc}`;
const actual = adapter.requestForQueryLeader(client.url, {
const actual = adapter.requestForQueryLeader(client.requestParams.bind(client), {
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 = {
Address: '211.245.86.75',
Port: '8500',
[META]: {
[DC.toLowerCase()]: dc,
[NSPACE.toLowerCase()]: nspace,
},
};
const actual = serializer.respondForQueryLeader(
function(cb) {