Skip to content

Commit

Permalink
refactor: Improve boot times
Browse files Browse the repository at this point in the history
  • Loading branch information
colin969 committed Mar 31, 2024
1 parent 8b37223 commit 45b6422
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ npm-debug.log.*

# Temp
/temp
/*.cpuprofile

# Launcher files (created during testing)
/config.json
Expand Down
57 changes: 45 additions & 12 deletions src/back/responses.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LogLevel } from '@shared/Log/interface';
import { MetaEditFile, MetaEditMeta } from '@shared/MetaEdit';
import { deepCopy, downloadFile, padEnd } from '@shared/Util';
import { BackIn, BackInit, BackOut, ComponentState, CurationImageEnum, DownloadDetails, GetRendererLoadedDataResponse } from '@shared/back/types';
import { BackIn, BackInit, BackOut, ComponentState, CurationImageEnum, DownloadDetails, GameOfTheDay, GetRendererLoadedDataResponse } from '@shared/back/types';
import { overwriteConfigData } from '@shared/config/util';
import { CURATIONS_FOLDER_EXPORTED, CURATIONS_FOLDER_TEMP, CURATIONS_FOLDER_WORKING, LOGOS, SCREENSHOTS, VIEW_PAGE_SIZE } from '@shared/constants';
import { convertGameToCurationMetaFile } from '@shared/curate/metaToMeta';
Expand Down Expand Up @@ -143,16 +143,14 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
state.socketServer.register(BackIn.GET_RENDERER_LOADED_DATA, async () => {
const libraries = await fpDatabase.findAllGameLibraries();

// Fetch update feed
let updateFeedMarkdown = '';
// Fetch update feed in background
if (state.preferences.updateFeedUrl) {
updateFeedMarkdown = await axios.get(state.preferences.updateFeedUrl, { timeout: 3000 })
axios.get(state.preferences.updateFeedUrl, { timeout: 3000 })
.then((res) => {
return res.data;
state.socketServer.broadcast(BackOut.UPDATE_FEED, res.data);
})
.catch((err) => {
log.debug('Launcher', `Failed to fetch news feed from ${state.preferences.updateFeedUrl}, ERROR: ${err}`);
return '';
});
} else {
log.debug('Launcher', 'No Update Feed URL specified');
Expand All @@ -161,7 +159,7 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
// Fetch GOTD file
const gotdUrl = state.config.gotdUrl;
const gotdPath = path.join(state.config.flashpointPath, 'Data', 'gotd.json');
await new Promise((resolve, reject) => {
const gotdDownload = new Promise((resolve, reject) => {
const thumbnailWriter = fs.createWriteStream(gotdPath);
axios.get(gotdUrl, { responseType: 'stream' })
.then((res) => {
Expand All @@ -180,15 +178,51 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
log.error('Launcher', 'Failed to download gotd list from ' + gotdUrl);
});

let gotdList = [];
let gotdList: GameOfTheDay[] | undefined = undefined;
try {
// Try to load the existing file first
gotdList = JSON.parse(fs.readFileSync(gotdPath, { encoding: 'utf8' })).games || [];
gotdList = gotdList.filter((g: any) => g.id !== '');
gotdList = (gotdList as GameOfTheDay[]).filter((g: any) => g.id !== '');

// Now let the download update in its own time
gotdDownload.then(() => {
try {
gotdList = JSON.parse(fs.readFileSync(gotdPath, { encoding: 'utf8' })).games || [];
gotdList = (gotdList as GameOfTheDay[]).filter((g: any) => g.id !== '');
state.socketServer.broadcast(BackOut.UPDATE_GOTD, gotdList);
} catch {
/** Bad download, ignore */
}
})
.catch(() => {
/** Bad download, ignore */
});
} catch {
/** Ignore */
// File doesn't exist, or broken, lets wait for a new one before trying again and returning
gotdList = await gotdDownload
.then(() => {
// Try loading again
let list = [];
try {
list = JSON.parse(fs.readFileSync(gotdPath, { encoding: 'utf8' })).games || [];
list = list.filter((g: any) => g.id !== '');
return list;
} catch {
/** Neither local or remote, give up */
return [];
}
})
.catch(() => {
/** Neither local or remote, give up */
return [];
});
}

state.platformAppPaths = processPlatformAppPaths(await fpDatabase.findPlatformAppPaths());
fpDatabase.findPlatformAppPaths().then((paths) => {
paths = processPlatformAppPaths(paths);
state.platformAppPaths = paths;
state.socketServer.broadcast(BackOut.UPDATE_PLATFORM_APP_PATHS, paths);
});

const res: GetRendererLoadedDataResponse = {
gotdList: gotdList,
Expand All @@ -199,7 +233,6 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
suggestions: state.suggestions,
platformAppPaths: state.platformAppPaths,
logoSets: Array.from(state.registry.logoSets.values()),
updateFeedMarkdown,
mad4fpEnabled: state.serviceInfo ? (state.serviceInfo.server.findIndex(s => s.mad4fp === true) !== -1) : false,
componentStatuses: state.componentStatuses,
shortcuts: state.shortcuts,
Expand Down
64 changes: 44 additions & 20 deletions src/renderer/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,25 +241,16 @@ export class App extends React.Component<AppProps> {
for (const index of data.done) {
switch (+index) { // Conversion to number, type safe bug
case BackInit.DATABASE: {
if (this.props.preferencesData.gameMetadataSources.length > 0) {
window.Shared.back.request(BackIn.PRE_UPDATE_INFO, this.props.preferencesData.gameMetadataSources[0])
.then((total) => {
this.props.dispatchMain({
type: MainActionType.UPDATE_UPDATE_INFO,
total
});
});
}
window.Shared.back.request(BackIn.GET_PLAYLISTS)
.then(data => {
if (data) {
this.props.dispatchMain({
type: MainActionType.ADD_LOADED,
loaded: [BackInit.PLAYLISTS],
});
this.props.setMainState({ playlists: data });
this.cachePlaylistIcons(data);
}
this.props.dispatchMain({
type: MainActionType.ADD_LOADED,
loaded: [BackInit.PLAYLISTS],
});
});
window.Shared.back.request(BackIn.GET_RENDERER_LOADED_DATA)
.then(data => {
Expand Down Expand Up @@ -290,6 +281,13 @@ export class App extends React.Component<AppProps> {
});
this.props.setTagCategories(data.tagCategories);
})
.then(() => {
console.log('fired db');
this.props.dispatchMain({
type: MainActionType.ADD_LOADED,
loaded: [index],
});
})
.then(async () => {
const data = await window.Shared.back.request(BackIn.GET_GAMES_TOTAL);
if (data) {
Expand All @@ -300,13 +298,20 @@ export class App extends React.Component<AppProps> {
}
})
.then(() => {
if (this.props.main.randomGames.length < RANDOM_GAME_ROW_COUNT) { this.rollRandomGames(true); }
if (this.props.main.randomGames.length < RANDOM_GAME_ROW_COUNT) {
this.rollRandomGames(true);
}
})
.then(() => {
this.props.dispatchMain({
type: MainActionType.ADD_LOADED,
loaded: [index],
});
if (this.props.preferencesData.gameMetadataSources.length > 0) {
window.Shared.back.request(BackIn.PRE_UPDATE_INFO, this.props.preferencesData.gameMetadataSources[0])
.then((total) => {
this.props.dispatchMain({
type: MainActionType.UPDATE_UPDATE_INFO,
total
});
});
}
});
break;
}
Expand Down Expand Up @@ -594,6 +599,24 @@ export class App extends React.Component<AppProps> {
});
});

window.Shared.back.register(BackOut.UPDATE_GOTD, (event, gotd) => {
this.props.setMainState({
gotdList: gotd
});
});

window.Shared.back.register(BackOut.UPDATE_FEED, (event, feed) => {
this.props.setMainState({
updateFeedMarkdown: feed
});
});

window.Shared.back.register(BackOut.UPDATE_PLATFORM_APP_PATHS, (event, paths) => {
this.props.setMainState({
platformAppPaths: paths
});
});

window.Shared.back.register(BackOut.POST_SYNC_CHANGES, (event, libraries, suggestions, platformAppPaths, cats, total) => {
this.props.dispatchMain({
type: MainActionType.POST_FPFSS_SYNC,
Expand Down Expand Up @@ -1813,8 +1836,9 @@ export class App extends React.Component<AppProps> {
alert(strings.dialog.unableToDeleteGame + '\n\n' + error);
});
};
cachePlaylistIcons(playlists: Playlist[]): void {
Promise.all(playlists.map(p => (async () => {

async cachePlaylistIcons(playlists: Playlist[]) {
return Promise.all(playlists.map(p => (async () => {
if (p.icon) { return cacheIcon(p.icon); }
})()))
.then(urls => {
Expand Down
9 changes: 6 additions & 3 deletions src/renderer/components/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { SimpleButton } from '../SimpleButton';
import { SizeProvider } from '../SizeProvider';

type OwnProps = {
gotdList: GameOfTheDay[];
gotdList: GameOfTheDay[] | undefined;
platforms: string[];
playlists: Playlist[];
/** Generator for game context menu */
Expand Down Expand Up @@ -59,7 +59,7 @@ export function HomePage(props: HomePageProps) {
const [updating, setUpdating] = React.useState(false);

const parsedGotdList = React.useMemo(() => {
return props.gotdList.map(g => {
return props.gotdList ? props.gotdList.map(g => {
const parts = g.date.split('-');
const year = parseInt(parts[0], 10);
const month = parseInt(parts[1], 10);
Expand All @@ -69,7 +69,7 @@ export function HomePage(props: HomePageProps) {
...g,
date: newDate
};
}).sort((a, b) => { return a.date.getTime() - b.date.getTime(); });
}).sort((a, b) => { return a.date.getTime() - b.date.getTime(); }) : [];
}, [props.gotdList]);

const [selectedGotd, setSelectedGotd] = React.useState(() => {
Expand Down Expand Up @@ -286,6 +286,9 @@ export function HomePage(props: HomePageProps) {
const extremeIconPath = React.useMemo(() => getExtremeIconURL(props.logoVersion), [props.logoVersion]);

const renderedGotd = React.useMemo(() => {
if (props.gotdList === undefined) {
return <></>; // No GOTD to display yet
}
const extremeTags = props.preferencesData.tagFilters.filter(t => !t.enabled && t.extreme).reduce<string[]>((prev, cur) => prev.concat(cur.tags), []);
return (
<HomePageBox
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import { RequestState } from './store/main/enums';

export type AppRouterProps = {
fpfssUser: FpfssUser | null;
gotdList: GameOfTheDay[];
gotdList: GameOfTheDay[] | undefined;
games: ViewGameSet;
randomGames: ViewGame[];
rollRandomGames: () => void;
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/store/main/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type View = {
export type ViewPageStates = Partial<Record<number, RequestState>>

export type MainState = {
gotdList: GameOfTheDay[];
gotdList: GameOfTheDay[] | undefined;
views: Record<string, View | undefined>; // views[id] = view
libraries: string[];
serverNames: string[];
Expand Down
13 changes: 11 additions & 2 deletions src/shared/back/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ export enum BackOut {
UPDATE_COMPONENT_STATUSES,
SET_VIEW_SEARCH_STATUS,

// Updates?
UPDATE_GOTD,
UPDATE_FEED,
UPDATE_PLATFORM_APP_PATHS,

// Metadata Sync
POST_SYNC_CHANGES,

Expand Down Expand Up @@ -444,6 +449,11 @@ export type BackOutTemplate = SocketTemplate<BackOut, {
[BackOut.UPDATE_COMPONENT_STATUSES]: (componentStatuses: ComponentStatus[]) => void;
[BackOut.SET_VIEW_SEARCH_STATUS]: (viewId: string, status: string | null) => void;

// Updates?
[BackOut.UPDATE_GOTD]: (gotd: GameOfTheDay[]) => void;
[BackOut.UPDATE_FEED]: (markdown: string) => void;
[BackOut.UPDATE_PLATFORM_APP_PATHS]: (paths: PlatformAppPathSuggestions) => void;

// Metadata Sync
[BackOut.POST_SYNC_CHANGES]: (libraries: string[], suggestions: GamePropSuggestions, platformAppPaths: PlatformAppPathSuggestions, cats: TagCategory[], total: number) => void;

Expand Down Expand Up @@ -535,7 +545,7 @@ export type GameOfTheDay = {
}

export type GetRendererLoadedDataResponse = {
gotdList: GameOfTheDay[],
gotdList: GameOfTheDay[] | undefined,
services: IService[];
libraries: string[];
suggestions: GamePropSuggestions;
Expand All @@ -544,7 +554,6 @@ export type GetRendererLoadedDataResponse = {
tagCategories: TagCategory[];
logoSets: LogoSet[];
platformAppPaths: PlatformAppPathSuggestions;
updateFeedMarkdown: string;
componentStatuses: ComponentStatus[];
shortcuts: Record<string, string[]>;
}
Expand Down

0 comments on commit 45b6422

Please sign in to comment.