feat: 🎸 Add fallback if client daemon is down or errors (#2085)
* feat: 🎸 Add fallback if client daemon is down or errors * test: 💍 Add tests for client daemon being down ✅ Closes: https://hashicorp.atlassian.net/browse/ICU-12026
This commit is contained in:
1 parent
9046c01238
commit
2e36d3c3e2
8 files changed
+195
-119
No files matched your search
@@ -39,6 +39,21 @@ const paginateResults = (array, page, pageSize) => {
|
||||
return array.slice(start, end);
|
||||
};
|
||||
|
||||
const fetchControllerData = async (context, next) => {
|
||||
const { data } = context.request;
|
||||
const { query } = data;
|
||||
const { recursive, scope_id, page, pageSize } = query;
|
||||
|
||||
// If we get an error or client daemon is unavailable, fall back to calling the API
|
||||
context.request.data.query = { recursive, scope_id };
|
||||
const results = await next(context.request);
|
||||
const models = results.content.toArray();
|
||||
|
||||
const paginatedResult = paginateResults(models, page, pageSize);
|
||||
paginatedResult.meta = { totalItems: models.length };
|
||||
return paginatedResult;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler to sit in front of the API request layer
|
||||
* so we can request from the daemon first
|
||||
@@ -60,18 +75,17 @@ export default class ClientDaemonHandler {
|
||||
'isClientDaemonRunning',
|
||||
);
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let { recursive, scope_id, page, pageSize, ...remainingQuery } = query;
|
||||
let searchQuery = '';
|
||||
|
||||
if (
|
||||
!Object.keys(supportedTypes).includes(type) ||
|
||||
!isClientDaemonRunning
|
||||
) {
|
||||
return next(context.request);
|
||||
return fetchControllerData(context, next);
|
||||
}
|
||||
|
||||
// TODO: Remove usages of recursive from callers and scope_id since
|
||||
// all calls to daemon are recursive, scope_id can be part of search query instead
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
let { recursive, scope_id, page, pageSize, ...remainingQuery } = query;
|
||||
let searchQuery = '';
|
||||
if (remainingQuery.query) {
|
||||
const { search, filters } = remainingQuery.query;
|
||||
|
||||
@@ -91,12 +105,20 @@ export default class ClientDaemonHandler {
|
||||
resource: pluralize(type),
|
||||
};
|
||||
|
||||
let clientDaemonResults = {};
|
||||
try {
|
||||
clientDaemonResults = await this.ipc.invoke(
|
||||
'searchClientDaemon',
|
||||
remainingQuery,
|
||||
);
|
||||
} catch (e) {
|
||||
return fetchControllerData(context, next);
|
||||
}
|
||||
|
||||
// Currently returns with a singular top level field with resource name
|
||||
// e.g. { targets: [...] } or { sessions: [..] }
|
||||
// So this just unwraps to the array, or undefined
|
||||
const [results] = Object.values(
|
||||
await this.ipc.invoke('searchClientDaemon', remainingQuery),
|
||||
);
|
||||
const [results] = Object.values(clientDaemonResults);
|
||||
const payload = { items: paginateResults(results, page, pageSize) };
|
||||
|
||||
const schema = store.modelFor(type);
|
||||
|
||||
Reference in new issue
Block a user