Skip to content

Commit

Permalink
feat(daemon+web): start impling session creation code, refactor some …
Browse files Browse the repository at this point in the history
…stuff in daemon
  • Loading branch information
IncognitoTGT committed Jan 11, 2025
1 parent fca2b77 commit c61a5b4
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 19 deletions.
5 changes: 2 additions & 3 deletions apps/daemon/src/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ import deleteSession from "./delete.js";
import { getFile, listFiles, sendFile } from "./file.js";
import manageSession from "./manage.js";
import screenshot from "./screenshot.js";
// fill this
export default new Elysia({ prefix: "/sessions" })
.put(
"/",
"/create",
async ({ body }) => {
const session = await createSession(body);
return {
success: true,
id: session.Id,
created: session.Created,
created: Number.parseInt(session.Created),
};
},
{
Expand Down
2 changes: 0 additions & 2 deletions apps/web/server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { createServer } from "node:http";
import auth from "@stardust/common/auth";
import { fromNodeHeaders } from "better-auth/node";
import { createProxyMiddleware } from "http-proxy-middleware";
import next from "next";
const dev = process.env.NODE_ENV !== "production";
Expand Down
16 changes: 8 additions & 8 deletions apps/web/src/app/(main)/create-session-button.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
"use client";
import { Button } from "@/components/ui/button";
// import { createSession } from "@/lib/session";
import { createSession } from "@/lib/session/create";
import { useRouter } from "next/navigation";
import { useTransition } from "react";
import { toast } from "sonner";
export function CreateSessionButton({ image }: { image: string }) {
export function CreateSessionButton({ workspace }: { workspace: string }) {
const [isPending, startTransition] = useTransition();
const router = useRouter();
return (
<Button
disabled={isPending}
onClick={() =>
startTransition(async () => {
// const session = await createSession(image).catch(() => {
// toast.error("Error creating session");
// });
// if (!session) return;
// router.push(`/view/${session[0].id}`);
console.log("w riz?");
const session = await createSession(workspace).catch(() => {
toast.error("Error creating session");
});
if (!session) return;
// @ts-expect-error to be fixed later
router.push(`/view/${session[0].id}`);
})
}
>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/app/(main)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default async function Dashboard() {
Close
</Button>
</DialogClose>
<CreateSessionButton image={workspace.dockerImage} />
<CreateSessionButton workspace={workspace.dockerImage} />
</DialogFooter>
</DialogContent>
</Dialog>
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/app/(main)/sessions/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import { CardTitle } from "@/components/ui/card";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { getNode } from "@/lib/sessions/client";
import { inspectSession } from "@/lib/sessions/inspect";
import { getNode } from "@/lib/session/client";
import { inspectSession } from "@/lib/session/inspect";
import auth from "@stardust/common/auth";
import db, { type SelectSession } from "@stardust/db";
import { Container, Loader2, PauseCircle, PlayCircle, ScreenShare, Square, Trash2 } from "lucide-react";
Expand Down
File renamed without changes.
59 changes: 59 additions & 0 deletions apps/web/src/lib/session/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"use server";

import auth from "@stardust/common/auth";
import { stardustConnector } from "@stardust/common/daemon/client";
import { getConfig } from "@stardust/config";
import db, { session } from "@stardust/db";
import { headers } from "next/headers";

export async function createSession(workspace: string) {
console.log(`✨ Stardust: Creating session using workspace ${workspace}`);
const config = getConfig();
const userSession = await auth.api.getSession({ headers: await headers() });
if (!userSession?.user) throw new Error("User not found");
// todo: move these limits to each node instead
if (config.session?.usageLimits) {
const { role, allSessions } = await db.transaction(async (tx) => ({
role: (
await tx.query.user.findFirst({
where: (user, { eq }) => eq(user.id, userSession?.user?.id as string),
columns: {
role: true,
},
})
)?.role,
allSessions: await tx.select().from(session),
}));
if (config.session?.usageLimits.instance && config.session?.usageLimits.instance <= allSessions.length)
throw new Error("Instance limit exceeded");
if (config.session.usageLimits.user && role !== "admin") {
const userSessions = allSessions.filter((v) => v.userId === userSession.user.id);
if (config.session?.usageLimits.user <= userSessions.length) throw new Error("User session limit exceeded");
}
}
// todo: make this pick node with lowest resource usage
const sessionNode = config.nodes[0];
const node = stardustConnector(`http://${sessionNode.hostname}:${sessionNode.port || 4000}`, sessionNode.token);
const { data: container, error } = await node.sessions.create.put({
workspace,
user: userSession.user.id,
});
if (error) throw error;
const expiry = new Date();
expiry.setMinutes(expiry.getMinutes() + (config.session?.keepaliveDuration || 1440));
return db
.insert(session)
.values({
id: container.id,
dockerImage: workspace,
createdAt: new Date(container.created),
expiresAt: expiry,
userId: userSession.user.id,
node: sessionNode.id,
})
.returning()
.catch(async (e) => {
await node.sessions({ ...container }).delete();
throw e;
});
}
File renamed without changes.
6 changes: 3 additions & 3 deletions packages/db/schema/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { relations } from "drizzle-orm";
import { bigint, pgTable, text } from "drizzle-orm/pg-core";
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";
import { user } from "./auth";

export type SelectUser = typeof user.$inferSelect;
Expand All @@ -20,8 +20,8 @@ export const session = pgTable("session", {
id: text("id").primaryKey().notNull(),
dockerImage: text("dockerImage").notNull(),
node: text("node").notNull(),
createdAt: bigint("createdAt", { mode: "number" }).notNull(),
expiresAt: bigint("expiresAt", { mode: "number" }).notNull(),
createdAt: timestamp("createdAt").notNull(),
expiresAt: timestamp("expiresAt").notNull(),
userId: text("userId")
.notNull()
.references(() => user.id),
Expand Down

0 comments on commit c61a5b4

Please sign in to comment.