Skip to content

Commit

Permalink
add database row for new query
Browse files Browse the repository at this point in the history
  • Loading branch information
eriktaubeneck committed Jun 7, 2024
1 parent 3051e42 commit 63088f7
Show file tree
Hide file tree
Showing 7 changed files with 504 additions and 29 deletions.
24 changes: 15 additions & 9 deletions server/app/query/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,41 @@ import {
IPARemoteServers,
RemoteServersType,
} from "@/app/query/servers";
import NewQueryId from "@/app/query/haikunator";
import { Branch, Branches, Commits } from "@/app/query/github";
import { createNewQuery, Query } from "@/data/query";
import { Database } from "@/data/supabaseTypes";

type QueryType = Database["public"]["Enums"]["query_type"];

export default function Page() {
const [queryId, setQueryId] = useState<string | null>(null);
const router = useRouter();

const handleFormSubmit = async (
event: FormEvent<HTMLFormElement>,
queryType: QueryType,
remoteServers: RemoteServersType,
) => {
event.preventDefault();
try {
const newQueryId = NewQueryId();
setQueryId(newQueryId);
// Send a POST request to start the process
const formData = new FormData(event.currentTarget);
const query: Query = await createNewQuery(formData, queryType);

setQueryId(query.displayId);

// Send a POST request to start the process
for (const remoteServer of Object.values(remoteServers)) {
const response = await fetch(remoteServer.startURL(newQueryId), {
const response = await fetch(remoteServer.startURL(query.uuid), {
method: "POST",
body: formData,
});
const data = await response.json();
const _data = await response.json();
}

await new Promise((f) => setTimeout(f, 1000));

// Redirect to /query/view/<newQueryId>
router.push(`/query/view/${newQueryId}`);
router.push(`/query/view/${query.displayId}`);
} catch (error) {
console.error("Error starting process:", error);
}
Expand All @@ -52,11 +58,11 @@ export default function Page() {
const handleDemoLogsFormSubmit = async (
event: FormEvent<HTMLFormElement>,
) => {
await handleFormSubmit(event, DemoLoggerRemoteServers);
await handleFormSubmit(event, "DEMO_LOGGER", DemoLoggerRemoteServers);
};

const handleIPAFormSubmit = async (event: FormEvent<HTMLFormElement>) => {
await handleFormSubmit(event, IPARemoteServers);
await handleFormSubmit(event, "IPA", IPARemoteServers);
};

return (
Expand Down
1 change: 1 addition & 0 deletions server/app/query/servers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface ServerLog {
}

export enum Status {
QUEUED = "QUEUED",
STARTING = "STARTING",
COMPILING = "COMPILING",
WAITING_TO_START = "WAITING_TO_START",
Expand Down
1 change: 1 addition & 0 deletions server/app/query/view/[id]/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type StatusClassNameMixinsType = {
};

const StatusClassNameMixins: StatusClassNameMixinsType = {
QUEUED: "bg-slate-300 dark:bg-slate-700",
STARTING: "bg-emerald-300 dark:bg-emerald-700 animate-pulse",
COMPILING: "bg-emerald-300 dark:bg-emerald-700 animate-pulse",
WAITING_TO_START: "bg-emerald-300 dark:bg-emerald-700 animate-pulse",
Expand Down
48 changes: 28 additions & 20 deletions server/app/query/view/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import {
initialRunTimeByRemoteServer,
} from "@/app/query/servers";
import { StatsComponent } from "@/app/query/view/[id]/charts";
import { getQuery, Query } from "@/data/query";

export default function Query({ params }: { params: { id: string } }) {
const [query, setQuery] = useState<Query | null>(null);
// display controls
const [logsHidden, setLogsHidden] = useState<boolean>(true);
const [statsHidden, setStatsHidden] = useState<boolean>(true);
Expand All @@ -44,9 +46,11 @@ export default function Query({ params }: { params: { id: string } }) {
}

const kill = async (remoteServers: RemoteServersType) => {
const query: Query = await getQuery(params.id);

const fetchPromises = Object.values(remoteServers).map(
async (remoteServer) => {
await fetch(remoteServer.killURL(params.id), {
await fetch(remoteServer.killURL(query.uuid), {
method: "POST",
});
},
Expand All @@ -56,26 +60,30 @@ export default function Query({ params }: { params: { id: string } }) {
};

useEffect(() => {
let webSockets: WebSocket[] = [];
for (const remoteServer of Object.values(IPARemoteServers)) {
const loggingWs = remoteServer.openLogSocket(params.id, setLogs);
const statusWs = remoteServer.openStatusSocket(
params.id,
setStatusByRemoteServer,
);
const statsWs = remoteServer.openStatsSocket(
params.id,
setStatsByRemoteServer,
setRunTimeByRemoteServer,
);
webSockets = [...webSockets, loggingWs, statusWs, statsWs];
}

return () => {
for (const ws of webSockets) {
ws.close();
(async () => {
const query: Query = await getQuery(params.id);
setQuery(query);
let webSockets: WebSocket[] = [];
for (const remoteServer of Object.values(IPARemoteServers)) {
const loggingWs = remoteServer.openLogSocket(query.uuid, setLogs);
const statusWs = remoteServer.openStatusSocket(
query.uuid,
setStatusByRemoteServer,
);
const statsWs = remoteServer.openStatsSocket(
query.uuid,
setStatsByRemoteServer,
setRunTimeByRemoteServer,
);
webSockets = [...webSockets, loggingWs, statusWs, statsWs];
}
};

return () => {
for (const ws of webSockets) {
ws.close();
}
};
})();
}, [params]);

return (
Expand Down
119 changes: 119 additions & 0 deletions server/data/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"use server";

import { notFound } from "next/navigation";
import { cookies } from "next/headers";
import { createServerClient } from "@supabase/ssr";
import { Database, Json } from "@/data/supabaseTypes";
import { Status } from "@/app/query/servers";
import NewQueryId from "@/app/query/haikunator";

type QueryRow = Database["public"]["Tables"]["queries"]["Row"];
type QueryType = Database["public"]["Enums"]["query_type"];

export interface Query {
uuid: string;
displayId: string;
type: QueryType;
status: Status;
formData: Json;
createdAt: string;
startedAt: string | null;
endedAt: string | null;
}

function processQueryData(data: QueryRow): Query {
return {
uuid: data.uuid,
displayId: data.display_id,
type: data.type as QueryType,
status: data.status as Status,
formData: data.form_data,
createdAt: data.created_at,
startedAt: data.started_at,
endedAt: data.ended_at,
};
}

export async function getQuery(displayId: string): Promise<Query> {
const cookieStore = cookies();

const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
},
},
);

const { status, data, error } = await supabase
.from("queries")
.select("*")
.eq("display_id", displayId)
.limit(1)
.maybeSingle();

if (error) {
console.error(error);
} else if (status === 200) {
if (data) {
return processQueryData(data);
} else {
notFound();
}
}
throw new Error(`${displayId} not found.`);
}

export async function createNewQuery(
formData: FormData,
queryType: QueryType,
): Promise<Query> {
const json = JSON.stringify(Object.fromEntries(formData));
const cookieStore = cookies();

const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
},
},
);

const newQueryId = NewQueryId();

const { data: uniqueDisplayId, error: rpcError } = await supabase.rpc(
"generate_unique_display_id",
{ p_display_id: newQueryId },
);

if (rpcError) {
throw new Error(`${rpcError}`);
}

const { data: queryRow, error: insertError } = await supabase
.from("queries")
.insert({
display_id: uniqueDisplayId,
status: "QUEUED",
type: queryType,
form_data: json,
})
.select()
.returns<QueryRow>()
.single();

if (insertError) {
throw new Error(`${insertError}`);
}

const query: Query = processQueryData(queryRow);
return query;
}
Loading

0 comments on commit 63088f7

Please sign in to comment.