Enhanced app update service with Redis caching for branch retrieval and current build information, improving performance and reducing API calls.
This commit is contained in:
parent
3d8e6325b2
commit
c507f708eb
@ -1,10 +1,16 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import config from '../../config.js';
|
import config from '../../config.js';
|
||||||
import log4js from 'log4js';
|
import log4js from 'log4js';
|
||||||
|
import { redisServer } from '../../database/redis.js';
|
||||||
|
|
||||||
const logger = log4js.getLogger('AppUpdate');
|
const logger = log4js.getLogger('AppUpdate');
|
||||||
logger.level = config.server.logLevel;
|
logger.level = config.server.logLevel;
|
||||||
|
|
||||||
|
const APP_UPDATE_PREFIX = 'appupdate:';
|
||||||
|
const APP_UPDATE_BRANCHES_KEY = `${APP_UPDATE_PREFIX}branches`;
|
||||||
|
const APP_UPDATE_CURRENT_PREFIX = `${APP_UPDATE_PREFIX}current:`;
|
||||||
|
const APP_UPDATE_TTL_SECONDS = 120;
|
||||||
|
|
||||||
const normalizeProjectUrl = (projectUrl) => {
|
const normalizeProjectUrl = (projectUrl) => {
|
||||||
if (typeof projectUrl !== 'string') return '';
|
if (typeof projectUrl !== 'string') return '';
|
||||||
return projectUrl.replace(/\/+$/, '');
|
return projectUrl.replace(/\/+$/, '');
|
||||||
@ -33,6 +39,11 @@ const mapArtifacts = (build, requestedBranch) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getBranchesFromJenkins = async () => {
|
const getBranchesFromJenkins = async () => {
|
||||||
|
const cached = await redisServer.getKey(APP_UPDATE_BRANCHES_KEY);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
const projectUrl = getProjectUrl();
|
const projectUrl = getProjectUrl();
|
||||||
if (!projectUrl) {
|
if (!projectUrl) {
|
||||||
throw new Error('Missing config.app.jenkinsProject');
|
throw new Error('Missing config.app.jenkinsProject');
|
||||||
@ -42,13 +53,16 @@ const getBranchesFromJenkins = async () => {
|
|||||||
const response = await axios.get(jenkinsUrl, { timeout: 10000 });
|
const response = await axios.get(jenkinsUrl, { timeout: 10000 });
|
||||||
const jobs = Array.isArray(response.data?.jobs) ? response.data.jobs : [];
|
const jobs = Array.isArray(response.data?.jobs) ? response.data.jobs : [];
|
||||||
|
|
||||||
return jobs
|
const branches = jobs
|
||||||
.map((job) => ({
|
.map((job) => ({
|
||||||
name: job.name,
|
name: job.name,
|
||||||
url: job.url,
|
url: job.url,
|
||||||
color: job.color,
|
color: job.color,
|
||||||
}))
|
}))
|
||||||
.filter((job) => typeof job.name === 'string' && typeof job.url === 'string');
|
.filter((job) => typeof job.name === 'string' && typeof job.url === 'string');
|
||||||
|
|
||||||
|
await redisServer.setKey(APP_UPDATE_BRANCHES_KEY, branches, APP_UPDATE_TTL_SECONDS);
|
||||||
|
return branches;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLatestBuildForBranch = async (branchUrl) => {
|
const getLatestBuildForBranch = async (branchUrl) => {
|
||||||
@ -91,7 +105,14 @@ export const appUpdateCurrentRouteHandler = async (req, res) => {
|
|||||||
return res.status(400).send({ error: 'branch query parameter is required' });
|
return res.status(400).send({ error: 'branch query parameter is required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const currentCacheKey = `${APP_UPDATE_CURRENT_PREFIX}${requestedBranch}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const cachedCurrent = await redisServer.getKey(currentCacheKey);
|
||||||
|
if (cachedCurrent) {
|
||||||
|
return res.send(cachedCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
const branches = await getBranchesFromJenkins();
|
const branches = await getBranchesFromJenkins();
|
||||||
const branch = branches.find((item) => item.name === requestedBranch);
|
const branch = branches.find((item) => item.name === requestedBranch);
|
||||||
|
|
||||||
@ -111,7 +132,7 @@ export const appUpdateCurrentRouteHandler = async (req, res) => {
|
|||||||
logger.error('Failed to parse version from build display name:', error);
|
logger.error('Failed to parse version from build display name:', error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.send({
|
const payload = {
|
||||||
branch: requestedBranch,
|
branch: requestedBranch,
|
||||||
buildNumber: build.number,
|
buildNumber: build.number,
|
||||||
version: version,
|
version: version,
|
||||||
@ -121,7 +142,10 @@ export const appUpdateCurrentRouteHandler = async (req, res) => {
|
|||||||
builtAt: new Date(build.timestamp).toISOString(),
|
builtAt: new Date(build.timestamp).toISOString(),
|
||||||
buildSource: source,
|
buildSource: source,
|
||||||
artifacts: mapArtifacts(build, requestedBranch),
|
artifacts: mapArtifacts(build, requestedBranch),
|
||||||
});
|
};
|
||||||
|
|
||||||
|
await redisServer.setKey(currentCacheKey, payload, APP_UPDATE_TTL_SECONDS);
|
||||||
|
return res.send(payload);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to fetch Jenkins build info:', error);
|
logger.error('Failed to fetch Jenkins build info:', error);
|
||||||
return res.status(500).send({
|
return res.status(500).send({
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user