Skip to content

Commit

Permalink
[Refactor] Refactor abort controllers to simplify creation/deletion (#…
Browse files Browse the repository at this point in the history
…3056)

* Create abort controllers inside runners

* Create abort controller only if not re-using a promise

* Delete abort controller of browser apps when closed
  • Loading branch information
arielj authored Oct 25, 2023
1 parent a89133e commit f5074b9
Show file tree
Hide file tree
Showing 19 changed files with 205 additions and 398 deletions.
9 changes: 8 additions & 1 deletion src/backend/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ import { readFileSync } from 'fs'
import { LegendaryCommand } from './storeManagers/legendary/commands'
import { commandToArgsArray } from './storeManagers/legendary/library'
import { searchForExecutableOnPath } from './utils/os/path'
import {
createAbortController,
deleteAbortController
} from './utils/aborthandler/aborthandler'

async function prepareLaunch(
gameSettings: GameSettings,
Expand Down Expand Up @@ -777,7 +781,6 @@ const commandsRunning = {}
async function callRunner(
commandParts: string[],
runner: RunnerProps,
abortController: AbortController,
options?: CallRunnerOptions
): Promise<ExecResult> {
const fullRunnerPath = join(runner.dir, runner.bin)
Expand Down Expand Up @@ -826,6 +829,9 @@ async function callRunner(
return currentPromise
}

const abortId = options?.abortId || appName || Math.random().toString()
const abortController = createAbortController(abortId)

let promise = new Promise<ExecResult>((res, rej) => {
const child = spawn(bin, commandParts, {
cwd: runner.dir,
Expand Down Expand Up @@ -934,6 +940,7 @@ async function callRunner(
.finally(() => {
// remove from list when done
delete commandsRunning[key]
deleteAbortController(abortId)
})

// keep track of which commands are running
Expand Down
8 changes: 1 addition & 7 deletions src/backend/save_sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ import {
writeFileSync
} from 'graceful-fs'
import { app } from 'electron'
import {
createAbortController,
deleteAbortController
} from './utils/aborthandler/aborthandler'
import { legendaryConfigPath } from './constants'
import { join } from 'path'
import { gameManagerMap, libraryManagerMap } from 'backend/storeManagers'
Expand Down Expand Up @@ -80,7 +76,6 @@ async function getDefaultLegendarySavePath(appName: string): Promise<string> {
}

logInfo(['Computing default save path for', appName], LogPrefix.Legendary)
const abortControllerName = appName + '-savePath'
await runLegendaryCommand(
{
subcommand: 'sync-saves',
Expand All @@ -89,8 +84,8 @@ async function getDefaultLegendarySavePath(appName: string): Promise<string> {
'--skip-download': true,
'--accept-path': true
},
createAbortController(abortControllerName),
{
abortId: appName + '-savePath',
logMessagePrefix: 'Getting default save path',
env: gameManagerMap['legendary'].isNative(appName)
? {}
Expand All @@ -99,7 +94,6 @@ async function getDefaultLegendarySavePath(appName: string): Promise<string> {
)
}
)
deleteAbortController(abortControllerName)

// If the save path was computed successfully, Legendary will have saved
// this path in `installed.json` (so the GameInfo)
Expand Down
102 changes: 34 additions & 68 deletions src/backend/storeManagers/gog/games.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import {
createAbortController,
deleteAbortController
} from '../../utils/aborthandler/aborthandler'
import {
importGame as importGogLibraryGame,
refreshInstalled,
Expand Down Expand Up @@ -148,15 +144,10 @@ export async function importGame(
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
platform: InstallPlatform
): Promise<ExecResult> {
const res = await runGogdlCommand(
['import', folderPath],
createAbortController(appName),
{
logMessagePrefix: `Importing ${appName}`
}
)

deleteAbortController(appName)
const res = await runGogdlCommand(['import', folderPath], {
abortId: appName,
logMessagePrefix: `Importing ${appName}`
})

if (res.abort) {
return res
Expand Down Expand Up @@ -314,17 +305,12 @@ export async function install(
onInstallOrUpdateOutput(appName, 'installing', data)
}

const res = await runGogdlCommand(
commandParts,
createAbortController(appName),
{
logFile: logPath,
onOutput,
logMessagePrefix: `Installing ${appName}`
}
)

deleteAbortController(appName)
const res = await runGogdlCommand(commandParts, {
abortId: appName,
logFile: logPath,
onOutput,
logMessagePrefix: `Installing ${appName}`
})

if (res.abort) {
return { status: 'abort' }
Expand Down Expand Up @@ -541,20 +527,15 @@ export async function launch(
`Launch Command: ${fullCommand}\n\nGame Log:\n`
)

const { error, abort } = await runGogdlCommand(
commandParts,
createAbortController(appName),
{
env: commandEnv,
wrappers,
logMessagePrefix: `Launching ${gameInfo.title}`,
onOutput: (output: string) => {
if (!logsDisabled) appendFileSync(logFileLocation(appName), output)
}
const { error, abort } = await runGogdlCommand(commandParts, {
abortId: appName,
env: commandEnv,
wrappers,
logMessagePrefix: `Launching ${gameInfo.title}`,
onOutput: (output: string) => {
if (!logsDisabled) appendFileSync(logFileLocation(appName), output)
}
)

deleteAbortController(appName)
})

if (abort) {
return true
Expand Down Expand Up @@ -618,16 +599,11 @@ export async function repair(appName: string): Promise<ExecResult> {
...workers
]

const res = await runGogdlCommand(
commandParts,
createAbortController(appName),
{
logFile: logPath,
logMessagePrefix: `Repairing ${appName}`
}
)

deleteAbortController(appName)
const res = await runGogdlCommand(commandParts, {
abortId: appName,
logFile: logPath,
logMessagePrefix: `Repairing ${appName}`
})

if (res.error) {
logError(['Failed to repair', `${appName}:`, res.error], LogPrefix.Gog)
Expand Down Expand Up @@ -676,16 +652,11 @@ export async function syncSaves(

logInfo([`Syncing saves for ${gameInfo.title}`], LogPrefix.Gog)

const res = await runGogdlCommand(
commandParts,
createAbortController(appName),
{
logMessagePrefix: `Syncing saves for ${gameInfo.title}`,
onOutput: (output) => (fullOutput += output)
}
)

deleteAbortController(appName)
const res = await runGogdlCommand(commandParts, {
abortId: appName,
logMessagePrefix: `Syncing saves for ${gameInfo.title}`,
onOutput: (output) => (fullOutput += output)
})

if (res.error) {
logError(
Expand Down Expand Up @@ -794,17 +765,12 @@ export async function update(
onInstallOrUpdateOutput(appName, 'updating', data)
}

const res = await runGogdlCommand(
commandParts,
createAbortController(appName),
{
logFile: logPath,
onOutput,
logMessagePrefix: `Updating ${appName}`
}
)

deleteAbortController(appName)
const res = await runGogdlCommand(commandParts, {
abortId: appName,
logFile: logPath,
onOutput,
logMessagePrefix: `Updating ${appName}`
})

if (res.abort) {
return { status: 'done' }
Expand Down
20 changes: 5 additions & 15 deletions src/backend/storeManagers/gog/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ import {
apiInfoCache
} from './electronStores'
import { callRunner } from '../../launcher'
import {
createAbortController,
deleteAbortController
} from '../../utils/aborthandler/aborthandler'
import { isOnline } from '../../online_monitor'
import i18next from 'i18next'

Expand Down Expand Up @@ -351,15 +347,10 @@ export async function getInstallInfo(
installPlatform === 'linux' ? 'windows' : installPlatform
]

const res = await runRunnerCommand(
commandParts,
createAbortController(appName),
{
logMessagePrefix: 'Getting game metadata'
}
)

deleteAbortController(appName)
const res = await runRunnerCommand(commandParts, {
abortId: appName,
logMessagePrefix: 'Getting game metadata'
})

if (!res.stdout || res.abort) {
logError(
Expand Down Expand Up @@ -1017,15 +1008,14 @@ export async function getLinuxInstallerInfo(appName: string): Promise<
*/
export async function runRunnerCommand(
commandParts: string[],
abortController: AbortController,
options?: CallRunnerOptions
): Promise<ExecResult> {
const { dir, bin } = getGOGdlBin()
const authConfig = join(app.getPath('userData'), 'gog_store', 'auth.json')

return callRunner(
['--auth-config-path', authConfig, ...commandParts],
{ name: 'gog', logPrefix: LogPrefix.Gog, bin, dir },
abortController,
{
...options,
verboseLogFile: gogdlLogFile
Expand Down
21 changes: 6 additions & 15 deletions src/backend/storeManagers/gog/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import { configStore } from './electronStores'
import { isOnline } from '../../online_monitor'
import { UserData } from 'common/types/gog'
import { runRunnerCommand } from './library'
import {
createAbortController,
deleteAbortController
} from 'backend/utils/aborthandler/aborthandler'
import { gogdlAuthConfig } from 'backend/constants'
import { clearCache } from 'backend/utils'

Expand All @@ -24,10 +20,9 @@ export class GOGUser {
logInfo('Logging using GOG credentials', LogPrefix.Gog)

// Gets token from GOG basaed on authorization code
const { stdout } = await runRunnerCommand(
['auth', '--code', code],
createAbortController('gogdl-auth')
)
const { stdout } = await runRunnerCommand(['auth', '--code', code], {
abortId: 'gogdl-auth'
})

try {
const data: GOGLoginData = JSON.parse(stdout.trim())
Expand All @@ -41,7 +36,6 @@ export class GOGUser {
)
return { status: 'error' }
}
deleteAbortController('gogdl-auth')
logInfo('Login Successful', LogPrefix.Gog)
configStore.set('isLoggedIn', true)
const userDetails = await this.getUserDetails()
Expand Down Expand Up @@ -100,12 +94,9 @@ export class GOGUser {
})
return
}
const { stdout } = await runRunnerCommand(
['auth'],
createAbortController('gogdl-get-credentials')
)

deleteAbortController('gogdl-get-credentials')
const { stdout } = await runRunnerCommand(['auth'], {
abortId: 'gogdl-get-credentials'
})
return JSON.parse(stdout)
}

Expand Down
Loading

0 comments on commit f5074b9

Please sign in to comment.