diff --git a/src/helpers/docker_queue.ts b/src/helpers/docker_queue.ts index a0440110..593420b1 100644 --- a/src/helpers/docker_queue.ts +++ b/src/helpers/docker_queue.ts @@ -115,64 +115,64 @@ const docker_cron = async () => { const new_containers: Docker.Container[] = []; if (contest_name === "THUAI6") { - if (queue_front.exposed === 1) { - const container_runner = await docker.createContainer({ - Image: utils.contest_image_map[contest_name].RUNNER_IMAGE, - HostConfig: { - Binds: [ - `${sub_base_dir}/${queue_front.room_id}/output:/usr/local/output`, - `${base_directory}/${contest_name}/${queue_front.map_id}/map:/usr/local/map`, - `${sub_base_dir}/${queue_front.room_id}/source:/usr/local/code` - ], - PortBindings: { - '8888/tcp': [{ HostPort: `${port}` }] - }, - AutoRemove: true, - Memory: 6 * 1024 * 1024 * 1024, - MemorySwap: 6 * 1024 * 1024 * 1024 - }, - ExposedPorts: { '8888/tcp': {} }, - Env: [ - `SCORE_URL=${score_url}`, - `FINISH_URL=${finish_url}`, - `TOKEN=${server_token}`, - `TEAM_LABELS=${JSON.stringify(queue_front.team_label_binds)}`, - `MAP_ID=${queue_front.map_id}` - ], - AttachStdin: false, - AttachStdout: false, - AttachStderr: false, - name: `${contest_name}_Runner_${queue_front.room_id}`, - }); - new_containers.push(container_runner); + // if (queue_front.exposed === 1) { + // const container_runner = await docker.createContainer({ + // Image: utils.contest_image_map[contest_name].RUNNER_IMAGE, + // HostConfig: { + // Binds: [ + // `${sub_base_dir}/${queue_front.room_id}/output:/usr/local/output`, + // `${base_directory}/${contest_name}/${queue_front.map_id}/map:/usr/local/map`, + // `${sub_base_dir}/${queue_front.room_id}/source:/usr/local/code` + // ], + // PortBindings: { + // '8888/tcp': [{ HostPort: `${port}` }] + // }, + // AutoRemove: true, + // Memory: 6 * 1024 * 1024 * 1024, + // MemorySwap: 6 * 1024 * 1024 * 1024 + // }, + // ExposedPorts: { '8888/tcp': {} }, + // Env: [ + // `SCORE_URL=${score_url}`, + // `FINISH_URL=${finish_url}`, + // `TOKEN=${server_token}`, + // `TEAM_LABELS=${JSON.stringify(queue_front.team_label_binds)}`, + // `MAP_ID=${queue_front.map_id}` + // ], + // AttachStdin: false, + // AttachStdout: false, + // AttachStderr: false, + // name: `${contest_name}_Runner_${queue_front.room_id}`, + // }); + // new_containers.push(container_runner); - } else { - const container_runner = await docker.createContainer({ - Image: utils.contest_image_map[contest_name].RUNNER_IMAGE, - HostConfig: { - Binds: [ - `${sub_base_dir}/${queue_front.room_id}/output:/usr/local/output`, - `${base_directory}/${contest_name}/${queue_front.map_id}/map:/usr/local/map`, - `${sub_base_dir}/${queue_front.room_id}/source:/usr/local/code` - ], - AutoRemove: true, - Memory: 6 * 1024 * 1024 * 1024, - MemorySwap: 6 * 1024 * 1024 * 1024 - }, - Env: [ - `SCORE_URL=${score_url}`, - `FINISH_URL=${finish_url}`, - `TOKEN=${server_token}`, - `TEAM_LABELS=${JSON.stringify(queue_front.team_label_binds)}`, - `MAP_ID=${queue_front.map_id}` - ], - AttachStdin: false, - AttachStdout: false, - AttachStderr: false, - name: `${contest_name}_Runner_${queue_front.room_id}`, - }); - new_containers.push(container_runner); - } + // } else { + // const container_runner = await docker.createContainer({ + // Image: utils.contest_image_map[contest_name].RUNNER_IMAGE, + // HostConfig: { + // Binds: [ + // `${sub_base_dir}/${queue_front.room_id}/output:/usr/local/output`, + // `${base_directory}/${contest_name}/${queue_front.map_id}/map:/usr/local/map`, + // `${sub_base_dir}/${queue_front.room_id}/source:/usr/local/code` + // ], + // AutoRemove: true, + // Memory: 6 * 1024 * 1024 * 1024, + // MemorySwap: 6 * 1024 * 1024 * 1024 + // }, + // Env: [ + // `SCORE_URL=${score_url}`, + // `FINISH_URL=${finish_url}`, + // `TOKEN=${server_token}`, + // `TEAM_LABELS=${JSON.stringify(queue_front.team_label_binds)}`, + // `MAP_ID=${queue_front.map_id}` + // ], + // AttachStdin: false, + // AttachStdout: false, + // AttachStderr: false, + // name: `${contest_name}_Runner_${queue_front.room_id}`, + // }); + // new_containers.push(container_runner); + // } } else { if (queue_front.envoy === 1) { @@ -268,7 +268,7 @@ const docker_cron = async () => { ], HostConfig: { Binds: [ - `${sub_base_dir}/${queue_front.room_id}/source:/usr/local/code` + `${sub_base_dir}/${queue_front.room_id}/source/${team_label_bind.team_id}:/usr/local/code` ], AutoRemove: true, Memory: 6 * 1024 * 1024 * 1024, @@ -277,7 +277,7 @@ const docker_cron = async () => { AttachStdin: false, AttachStdout: false, AttachStderr: false, - name: `${contest_name}_Client_${team_label_bind.team_id}_${queue_front.room_id}`, + name: `${contest_name}_Client_${queue_front.room_id}_${team_label_bind.team_id}`, }); return container_client; }); diff --git a/src/helpers/hasura.ts b/src/helpers/hasura.ts index 44366503..ad123495 100644 --- a/src/helpers/hasura.ts +++ b/src/helpers/hasura.ts @@ -2,7 +2,18 @@ import { gql } from "graphql-request"; import { client } from ".."; -// query contest_name from contest_id + +/** + ============================================================================ + ============================ QUERY FUNCTIONS =============================== + ============================================================================ + */ + +/** + * query contest_name from contest_id + * @param {string} contest_id + * @returns {string} contest_name + */ export const get_contest_name: any = async (contest_id: string) => { const query_contest_name = await client.request( gql` @@ -19,7 +30,12 @@ export const get_contest_name: any = async (contest_id: string) => { return query_contest_name.contest[0]?.name ?? null; }; -// query contest_id from contest_name + +/** + * query contest_id from contest_name + * @param {string} contest_name + * @returns {string} contest_id + */ export const get_contest_id: any = async (contest_name: string) => { const query_contest_id = await client.request( gql` @@ -36,7 +52,12 @@ export const get_contest_id: any = async (contest_name: string) => { return query_contest_id.contest[0]?.id ?? null; }; -// query contest settings from contest_id + +/** + * query contest settings from contest_id + * @param {string} contest_id + * @returns {object} {arena_switch, code_upload_switch, playback_switch, playground_switch, stream_switch, team_switch} + */ export const get_contest_settings: any = async (contest_id: string) => { const query_contest_settings = await client.request( gql` @@ -66,7 +87,13 @@ export const get_contest_settings: any = async (contest_id: string) => { }; }; -// query team_id from user_uuid and contest_id + +/** + * query team_id from user_uuid and contest_id + * @param {string} user_uuid + * @param {string} contest_id + * @returns {string} team_id + */ export const get_team_from_user: any = async (user_uuid: string, contest_id: string) => { const query_team_id = await client.request( gql` @@ -84,7 +111,12 @@ export const get_team_from_user: any = async (user_uuid: string, contest_id: str return query_team_id.contest_team_member[0]?.team_id ?? null; }; -// query team_id from code_id + +/** + * query team_id from code_id + * @param {string} code_id + * @returns {string} team_id + */ export const get_team_from_code: any = async (code_id: string) => { const query_team_id = await client.request( gql` @@ -223,7 +255,13 @@ export const get_teams_contest_score: any = async (team_ids: Array) => { })) ?? []; }; -// query manager_uuid from user_uuid and contest_id + +/** + * query manager_uuid from user_uuid and contest_id + * @param {string} user_uuid + * @param {string} contest_id + * @returns {string} manager_uuid + */ export const get_maneger_from_user: any = async (user_uuid: string, contest_id: string) => { const query_if_manager = await client.request( gql` @@ -241,7 +279,12 @@ export const get_maneger_from_user: any = async (user_uuid: string, contest_id: return query_if_manager.contest_manager[0]?.user_uuid ?? null; } -// query language and contest_id from code_id + +/** + * query language and contest_id from code_id + * @param {string} code_id + * @returns {object} {contest_id, contest_name, team_id, language, compile_status} + */ export const query_code: any = async (code_id: string) => { const query_all_from_code = await client.request( gql` @@ -353,61 +396,6 @@ export const get_player_code: any = async (team_id: string, player_label: string } -/** - * insert a new room - * @param {string} contest_id - * @param {string} status - * @param {string} map_id - * @returns {string} room_id - */ -export const insert_room: any = async (contest_id: string, status: string, map_id: string) => { - const insert_room = await client.request( - gql` - mutation insert_room($contest_id: uuid!, $status: String!, $map_id: uuid!) { - insert_contest_room_one(object: {contest_id: $contest_id, status: $status, map_id: $map_id}) { - room_id - } - } - `, - { - contest_id: contest_id, - status: status, - map_id: map_id - } - ); - - return insert_room.insert_contest_room_one?.room_id ?? null; -} - - -/** - * insert a new competition room - * @param {string} contest_id - * @param {string} status - * @param {string} map_id - * @param {string} round_id - * @returns {string} room_id - */ -export const insert_room_competition: any = async (contest_id: string, status: string, map_id: string, round_id: string) => { - const insert_room = await client.request( - gql` - mutation insert_room($contest_id: uuid!, $status: String!, $map_id: uuid!, $round_id: uuid!) { - insert_contest_room_one(object: {contest_id: $contest_id, status: $status, map_id: $map_id, round_id: $round_id}) { - room_id - } - } - `, - { - contest_id: contest_id, - status: status, - map_id: map_id, - round_id: round_id - } - ); - - return insert_room.insert_contest_room_one?.room_id ?? null; -} - /** * query roound info from round_id @@ -537,6 +525,69 @@ export const get_all_maps: any = async () => { } + +/** + ============================================================================ + ============================ INSERT FUNCTIONS ============================== + ============================================================================ + */ + +/** + * insert a new room + * @param {string} contest_id + * @param {string} status + * @param {string} map_id + * @returns {string} room_id + */ +export const insert_room: any = async (contest_id: string, status: string, map_id: string) => { + const insert_room = await client.request( + gql` + mutation insert_room($contest_id: uuid!, $status: String!, $map_id: uuid!) { + insert_contest_room_one(object: {contest_id: $contest_id, status: $status, map_id: $map_id}) { + room_id + } + } + `, + { + contest_id: contest_id, + status: status, + map_id: map_id + } + ); + + return insert_room.insert_contest_room_one?.room_id ?? null; +} + + +/** + * insert a new competition room + * @param {string} contest_id + * @param {string} status + * @param {string} map_id + * @param {string} round_id + * @returns {string} room_id + */ +export const insert_room_competition: any = async (contest_id: string, status: string, map_id: string, round_id: string) => { + const insert_room = await client.request( + gql` + mutation insert_room($contest_id: uuid!, $status: String!, $map_id: uuid!, $round_id: uuid!) { + insert_contest_room_one(object: {contest_id: $contest_id, status: $status, map_id: $map_id, round_id: $round_id}) { + room_id + } + } + `, + { + contest_id: contest_id, + status: status, + map_id: map_id, + round_id: round_id + } + ); + + return insert_room.insert_contest_room_one?.room_id ?? null; +} + + /** * Insert room_teams * @param {string} room_id @@ -571,6 +622,12 @@ export const insert_room_teams: any = async (room_id: string, team_ids: Array { const language = code_languages_flat[index]; const code_file_name = language === "cpp" ? `${player_code}` : `${player_code}.py`; const arena_file_name = language === "cpp" ? `${player_labels_flat[index]}` : `${player_labels_flat[index]}.py`; - return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, - `${base_directory}/${contest_name}/arena/${room_id}/source/${arena_file_name}`) + return fs.mkdir(`${base_directory}/${contest_name}/arena/${room_id}/source/${team_ids_flat[index]}`, { recursive: true }) + .then(() => { + return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, + `${base_directory}/${contest_name}/arena/${room_id}/source/${team_ids_flat[index]}/${arena_file_name}`) + }) .then(() => { return Promise.resolve(true); }) diff --git a/src/routes/competition.ts b/src/routes/competition.ts index efed433f..bbdb56a1 100644 --- a/src/routes/competition.ts +++ b/src/routes/competition.ts @@ -191,15 +191,23 @@ router.post("/start-all", authenticate(), async (req, res) => { console.log("Map downloaded!"); const pairs_unfold: [team_label1: string, team_label2: string, team1: string, team2: string][] = []; - for (let i = 0; i < team_labels_unique.length; i++) { - for (let j = i + 1; j < team_labels_unique.length; j++) { - for (let k = 0; k < team_list_available.length; k++) { - for (let l = k + 1; l < team_list_available.length; l++) { - pairs_unfold.push([team_labels_unique[i], team_labels_unique[j], team_list_available[k], team_list_available[l]]); - pairs_unfold.push([team_labels_unique[j], team_labels_unique[i], team_list_available[k], team_list_available[l]]); - } - } + if (team_labels_unique.length === 1) { + for (let i = 0; i < team_list_available.length; i++) { + for (let j = i + 1; j < team_list_available.length; j++) { + pairs_unfold.push([team_labels_unique[0], team_labels_unique[0], team_list_available[i], team_list_available[j]]); } + } + } else { + for (let i = 0; i < team_labels_unique.length; i++) { + for (let j = i + 1; j < team_labels_unique.length; j++) { + for (let k = 0; k < team_list_available.length; k++) { + for (let l = k + 1; l < team_list_available.length; l++) { + pairs_unfold.push([team_labels_unique[i], team_labels_unique[j], team_list_available[k], team_list_available[l]]); + pairs_unfold.push([team_labels_unique[j], team_labels_unique[i], team_list_available[k], team_list_available[l]]); + } + } + } + } } const start_competition_promises = pairs_unfold.map(pair => { @@ -208,8 +216,10 @@ router.post("/start-all", authenticate(), async (req, res) => { const team1_id = pair[2]; const team2_id = pair[3]; - const details_list_filtered_1 = details_list_available.filter(player => player.team_id === team1_id && player.team_label === team1_label); - const details_list_filtered_2 = details_list_available.filter(player => player.team_id === team2_id && player.team_label === team2_label); + const details_list_filtered_1 = details_list_available.filter(player => + player.team_id === team1_id && player.team_label === team1_label); + const details_list_filtered_2 = details_list_available.filter(player => + player.team_id === team2_id && player.team_label === team2_label); const player_labels_flat = details_list_filtered_1.map(player => player.player_label).concat( details_list_filtered_2.map(player => player.player_label)); const team1_codes = details_list_filtered_1.map(player => player.code_id); @@ -245,8 +255,11 @@ router.post("/start-all", authenticate(), async (req, res) => { const language = code_languages_flat[index]; const code_file_name = language === "cpp" ? `${player_code}` : `${player_code}.py`; const competition_file_name = language === "cpp" ? `${player_labels_flat[index]}` : `${player_labels_flat[index]}.py`; - return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, - `${base_directory}/${contest_name}/competition/${room_id}/source/${competition_file_name}`) + return fs.mkdir(`${base_directory}/${contest_name}/arena/${room_id}/source/${team_ids_flat[index]}`, { recursive: true }) + .then(() => { + return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, + `${base_directory}/${contest_name}/competition/${room_id}/source/${team_ids_flat[index]}/${competition_file_name}`) + }) .then(() => { return Promise.resolve(true); }) @@ -576,8 +589,11 @@ router.post("/start-one", authenticate(), async (req, res) => { const language = code_languages_flat[index]; const code_file_name = language === "cpp" ? `${player_code}` : `${player_code}.py`; const arena_file_name = language === "cpp" ? `${player_labels_flat[index]}` : `${player_labels_flat[index]}.py`; - return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, - `${base_directory}/${contest_name}/competition/${room_id}/source/${arena_file_name}`) + return fs.mkdir(`${base_directory}/${contest_name}/arena/${room_id}/source/${team_ids_flat[index]}`, { recursive: true }) + .then(() => { + return fs.copyFile(`${base_directory}/${contest_name}/code/${team_ids_flat[index]}/${code_file_name}`, + `${base_directory}/${contest_name}/competition/${room_id}/source/${team_ids_flat[index]}/${arena_file_name}`) + }) .then(() => { return Promise.resolve(true); })