unity-builder/src/model/cli/shared-workspace-locking.ts

116 lines
4.0 KiB
TypeScript
Raw Normal View History

2022-09-16 22:51:19 +00:00
import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system';
import * as fs from 'fs';
2022-09-17 03:38:00 +00:00
import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger';
2022-09-17 03:41:41 +00:00
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';
2022-09-16 21:24:23 +00:00
export class SharedWorkspaceLocking {
2022-09-29 20:30:34 +00:00
public static async GetLockedWorkspace(workspaceIfCreated: string, runId: string) {
2022-09-17 03:41:41 +00:00
if (!CloudRunnerOptions.retainWorkspaces) {
return;
}
2022-09-29 20:30:34 +00:00
const workspaces = await SharedWorkspaceLocking.GetFreeWorkspaces();
2022-09-16 21:24:23 +00:00
for (const element of workspaces) {
2022-09-29 20:30:34 +00:00
if (await SharedWorkspaceLocking.LockWorkspace(element, runId)) {
2022-09-16 21:24:23 +00:00
return element;
}
}
2022-09-29 20:30:34 +00:00
return await SharedWorkspaceLocking.CreateLockableWorkspace(workspaceIfCreated);
2022-09-16 21:24:23 +00:00
}
2022-09-29 20:30:34 +00:00
public static async GetFreeWorkspaces(): Promise<string[]> {
const result: string[] = [];
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces();
for (const element of workspaces) {
if (!(await SharedWorkspaceLocking.IsWorkspaceLocked(element))) {
result.push(element);
}
}
return result;
}
public static async GetAllWorkspaces(): Promise<string[]> {
return (await SharedWorkspaceLocking.ReadLines(`aws s3 ls s3://game-ci-test-storage/locks/`)).map((x) =>
x.replace(`/`, ``),
);
2022-09-16 21:24:23 +00:00
}
2022-09-29 20:30:34 +00:00
public static async GetAllLocks(workspace: string): Promise<string[]> {
return (await SharedWorkspaceLocking.ReadLines(`aws s3 ls s3://game-ci-test-storage/locks/${workspace}/`)).map(
(x) => x.replace(`/`, ``),
);
}
private static async ReadLines(command: string): Promise<string[]> {
const result = await CloudRunnerSystem.Run(command, false, true);
return result
.split(`\n`)
.map((x) => x.replace(`\r`, ``))
.filter((x) => x !== ``)
.map((x) => {
const lineValues = x.split(` `);
return lineValues[lineValues.length - 1];
});
2022-09-16 21:24:23 +00:00
}
2022-09-29 20:30:34 +00:00
public static async LockWorkspace(workspace: string, runId: string): Promise<boolean> {
const file = `${Date.now()}_${runId}_lock`;
2022-09-16 22:51:19 +00:00
fs.writeFileSync(file, '');
2022-09-29 20:30:34 +00:00
await CloudRunnerSystem.Run(
`aws s3 cp ./${file} s3://game-ci-test-storage/locks/${workspace}/${file}`,
false,
true,
);
2022-09-16 22:51:19 +00:00
fs.rmSync(file);
return SharedWorkspaceLocking.HasWorkspaceLock(workspace);
}
2022-09-29 20:30:34 +00:00
public static async ReleaseWorkspace(workspace: string, runId: string): Promise<boolean> {
const file = (await SharedWorkspaceLocking.GetAllLocks(workspace)).filter((x) => x.includes(`_${runId}_lock`));
CloudRunnerLogger.log(`${JSON.stringify(await SharedWorkspaceLocking.GetAllLocks(workspace))}`);
CloudRunnerLogger.log(`Deleting file ${file}`);
CloudRunnerLogger.log(`aws s3 rm s3://game-ci-test-storage/locks/${workspace}/${file}`);
await CloudRunnerSystem.Run(`aws s3 rm s3://game-ci-test-storage/locks/${workspace}/${file}`, false, true);
return !SharedWorkspaceLocking.HasWorkspaceLock(workspace);
}
2022-09-16 22:51:19 +00:00
public static async HasWorkspaceLock(workspace: string): Promise<boolean> {
2022-09-17 03:38:00 +00:00
CloudRunnerLogger.log(
2022-09-29 20:30:34 +00:00
(await CloudRunnerSystem.Run(`aws s3 ls s3://game-ci-test-storage/locks/${workspace}/`, false, true))
2022-09-17 03:38:00 +00:00
.split('\n')
.map((x) => {
return x.split(' ');
})
.length.toString(),
);
2022-09-16 22:51:19 +00:00
2022-09-16 21:24:23 +00:00
return true;
}
2022-09-29 20:30:34 +00:00
public static async IsWorkspaceLocked(workspace: string): Promise<boolean> {
const files = await SharedWorkspaceLocking.ReadLines(`aws s3 ls s3://game-ci-test-storage/locks/${workspace}/`);
// 1 Because we expect 1 workspace file to exist in every workspace folder
return files.length > 1;
}
2022-09-17 04:09:36 +00:00
public static async CreateLockableWorkspace(workspace: string) {
2022-09-29 20:30:34 +00:00
const file = `${Date.now()}_workspace`;
2022-09-17 04:09:36 +00:00
fs.writeFileSync(file, '');
2022-09-29 20:30:34 +00:00
await CloudRunnerSystem.Run(
`aws s3 cp ./${file} s3://game-ci-test-storage/locks/${workspace}/${file}`,
false,
true,
);
fs.rmSync(file);
2022-09-17 04:44:07 +00:00
2022-09-29 20:30:34 +00:00
return workspace;
2022-09-17 04:09:36 +00:00
}
2022-09-16 21:24:23 +00:00
// eslint-disable-next-line no-unused-vars
public static ReleaseLock(workspace: string) {}
}
2022-09-16 18:48:40 +00:00
export default SharedWorkspaceLocking;