debian-mirror-gitlab/config/helpers/incremental_webpack_compiler/history.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

177 lines
4.4 KiB
JavaScript
Raw Normal View History

2021-11-11 11:23:49 +05:30
/* eslint-disable max-classes-per-file, no-underscore-dangle */
const fs = require('fs');
const log = require('./log');
const ESSENTIAL_ENTRY_POINTS = [
// Login page
'pages.sessions.new',
// Explore page
'pages.root',
];
// TODO: Find a way to keep this list up-to-date/relevant.
const COMMON_ENTRY_POINTS = [
...ESSENTIAL_ENTRY_POINTS,
'pages.admin',
'pages.admin.dashboard',
'pages.dashboard.groups.index',
'pages.dashboard.projects.index',
'pages.groups.new',
'pages.groups.show',
'pages.profiles.preferences.show',
'pages.projects.commit.show',
'pages.projects.edit',
'pages.projects.issues.index',
'pages.projects.issues.new',
'pages.projects.issues.show',
'pages.projects.jobs.show',
'pages.projects.merge_requests.index',
'pages.projects.merge_requests.show',
'pages.projects.milestones.index',
'pages.projects.new',
'pages.projects.pipelines.index',
'pages.projects.pipelines.show',
'pages.projects.settings.ci_cd.show',
'pages.projects.settings.repository.show',
'pages.projects.show',
'pages.users',
];
/**
* The History class is responsible for tracking which entry points have been
* requested, and persisting/loading the history to/from disk.
*/
class History {
constructor(historyFilePath) {
this._historyFilePath = historyFilePath;
this._history = {};
this._loadHistoryFile();
}
onRequestEntryPoint(entryPoint) {
const wasVisitedRecently = this.isRecentlyVisited(entryPoint);
this._addEntryPoint(entryPoint);
this._writeHistoryFile();
return wasVisitedRecently;
}
// eslint-disable-next-line class-methods-use-this
isRecentlyVisited() {
return true;
}
// eslint-disable-next-line class-methods-use-this
get size() {
return 0;
}
// Private methods
_addEntryPoint(entryPoint) {
if (!this._history[entryPoint]) {
this._history[entryPoint] = { lastVisit: null, count: 0 };
}
this._history[entryPoint].lastVisit = Date.now();
this._history[entryPoint].count += 1;
}
_writeHistoryFile() {
try {
fs.writeFileSync(this._historyFilePath, JSON.stringify(this._history), 'utf8');
} catch (error) {
log('Warning Could not write to history', error.message);
}
}
_loadHistoryFile() {
try {
fs.accessSync(this._historyFilePath);
} catch (e) {
// History file doesn't exist; attempt to seed it, and return early
this._seedHistory();
return;
}
// History file already exists; attempt to load its contents into memory
try {
this._history = JSON.parse(fs.readFileSync(this._historyFilePath, 'utf8'));
const historySize = Object.keys(this._history).length;
log(`Successfully loaded history containing ${historySize} entry points`);
} catch (error) {
log('Could not load history', error.message);
}
}
/**
* Seeds a reasonable set of approximately the most common entry points to
* seed the history. This helps to avoid fresh GDK installs showing the
* compiling overlay too often.
*/
_seedHistory() {
log('Seeding history...');
COMMON_ENTRY_POINTS.forEach((entryPoint) => this._addEntryPoint(entryPoint));
this._writeHistoryFile();
}
}
const MS_PER_DAY = 1000 * 60 * 60 * 24;
/**
* The HistoryWithTTL class adds LRU-like behaviour onto the base History
* behaviour. Entry points visited within the last `ttl` days are considered
* "recent", and therefore should be eagerly compiled.
*/
class HistoryWithTTL extends History {
constructor(historyFilePath, ttl) {
super(historyFilePath);
this._ttl = ttl;
this._calculateRecentEntryPoints();
}
onRequestEntryPoint(entryPoint) {
const wasVisitedRecently = super.onRequestEntryPoint(entryPoint);
this._calculateRecentEntryPoints();
return wasVisitedRecently;
}
isRecentlyVisited(entryPoint) {
return this._recentEntryPoints.has(entryPoint);
}
get size() {
return this._recentEntryPoints.size;
}
// Private methods
_calculateRecentEntryPoints() {
const oldestVisitAllowed = Date.now() - MS_PER_DAY * this._ttl;
const recentEntryPoints = Object.entries(this._history).reduce(
(acc, [entryPoint, { lastVisit }]) => {
if (lastVisit > oldestVisitAllowed) {
acc.push(entryPoint);
}
return acc;
},
[],
);
this._recentEntryPoints = new Set([...ESSENTIAL_ENTRY_POINTS, ...recentEntryPoints]);
}
}
module.exports = {
History,
HistoryWithTTL,
};