From c7727fc1bee1474c64547c3eee2795413a8adf1f Mon Sep 17 00:00:00 2001 From: bennykok Date: Sat, 27 Jan 2024 14:21:59 +0800 Subject: [PATCH] feat: revamp cold start time counter --- web/drizzle/0045_careful_cerise.sql | 3 + web/drizzle/meta/0045_snapshot.json | 1297 +++++++++++++++++++++ web/drizzle/meta/_journal.json | 7 + web/src/app/(app)/api/update-run/route.ts | 34 +- web/src/components/RunDisplay.tsx | 114 +- web/src/db/schema.ts | 75 +- web/src/server/createRun.ts | 9 - web/src/server/findAllRuns.tsx | 70 +- 8 files changed, 1456 insertions(+), 153 deletions(-) create mode 100644 web/drizzle/0045_careful_cerise.sql create mode 100644 web/drizzle/meta/0045_snapshot.json diff --git a/web/drizzle/0045_careful_cerise.sql b/web/drizzle/0045_careful_cerise.sql new file mode 100644 index 0000000..52880d1 --- /dev/null +++ b/web/drizzle/0045_careful_cerise.sql @@ -0,0 +1,3 @@ +ALTER TYPE "workflow_run_status" ADD VALUE 'started';--> statement-breakpoint +ALTER TYPE "workflow_run_status" ADD VALUE 'queued';--> statement-breakpoint +ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "queued_at" timestamp; \ No newline at end of file diff --git a/web/drizzle/meta/0045_snapshot.json b/web/drizzle/meta/0045_snapshot.json new file mode 100644 index 0000000..9b3095a --- /dev/null +++ b/web/drizzle/meta/0045_snapshot.json @@ -0,0 +1,1297 @@ +{ + "id": "7dcec370-7a85-42ec-90b6-1fe4bfa8884c", + "prevId": "9328bbb1-3335-46cb-a005-c00f9959ab4b", + "version": "5", + "dialect": "pg", + "tables": { + "api_keys": { + "name": "api_keys", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "revoked": { + "name": "revoked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "api_keys_user_id_users_id_fk": { + "name": "api_keys_user_id_users_id_fk", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "api_keys_key_unique": { + "name": "api_keys_key_unique", + "nullsNotDistinct": false, + "columns": [ + "key" + ] + } + } + }, + "auth_requests": { + "name": "auth_requests", + "schema": "comfyui_deploy", + "columns": { + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_hash": { + "name": "api_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expired_date": { + "name": "expired_date", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "deployments": { + "name": "deployments", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "workflow_version_id": { + "name": "workflow_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workflow_id": { + "name": "workflow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "machine_id": { + "name": "machine_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "share_slug": { + "name": "share_slug", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "showcase_media": { + "name": "showcase_media", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "environment": { + "name": "environment", + "type": "deployment_environment", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "deployments_user_id_users_id_fk": { + "name": "deployments_user_id_users_id_fk", + "tableFrom": "deployments", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployments_workflow_version_id_workflow_versions_id_fk": { + "name": "deployments_workflow_version_id_workflow_versions_id_fk", + "tableFrom": "deployments", + "tableTo": "workflow_versions", + "columnsFrom": [ + "workflow_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployments_workflow_id_workflows_id_fk": { + "name": "deployments_workflow_id_workflows_id_fk", + "tableFrom": "deployments", + "tableTo": "workflows", + "columnsFrom": [ + "workflow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "deployments_machine_id_machines_id_fk": { + "name": "deployments_machine_id_machines_id_fk", + "tableFrom": "deployments", + "tableTo": "machines", + "columnsFrom": [ + "machine_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "deployments_share_slug_unique": { + "name": "deployments_share_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "share_slug" + ] + } + } + }, + "machines": { + "name": "machines", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "auth_token": { + "name": "auth_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "machine_type", + "primaryKey": false, + "notNull": true, + "default": "'classic'" + }, + "status": { + "name": "status", + "type": "machine_status", + "primaryKey": false, + "notNull": true, + "default": "'ready'" + }, + "snapshot": { + "name": "snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "models": { + "name": "models", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "gpu": { + "name": "gpu", + "type": "machine_gpu", + "primaryKey": false, + "notNull": false + }, + "build_machine_instance_id": { + "name": "build_machine_instance_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "build_log": { + "name": "build_log", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "machines_user_id_users_id_fk": { + "name": "machines_user_id_users_id_fk", + "tableFrom": "machines", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "models": { + "name": "models", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_volume_id": { + "name": "user_volume_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model_name": { + "name": "model_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "folder_path": { + "name": "folder_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_id": { + "name": "civitai_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_version_id": { + "name": "civitai_version_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_url": { + "name": "civitai_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_download_url": { + "name": "civitai_download_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "civitai_model_response": { + "name": "civitai_model_response", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hf_url": { + "name": "hf_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "s3_url": { + "name": "s3_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_url": { + "name": "client_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_public": { + "name": "is_public", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "status": { + "name": "status", + "type": "resource_upload", + "primaryKey": false, + "notNull": true, + "default": "'started'" + }, + "upload_machine_id": { + "name": "upload_machine_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "upload_type": { + "name": "upload_type", + "type": "model_upload_type", + "primaryKey": false, + "notNull": true + }, + "model_type": { + "name": "model_type", + "type": "model_type", + "primaryKey": false, + "notNull": true, + "default": "'checkpoint'" + }, + "error_log": { + "name": "error_log", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "models_user_id_users_id_fk": { + "name": "models_user_id_users_id_fk", + "tableFrom": "models", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "models_user_volume_id_user_volume_id_fk": { + "name": "models_user_volume_id_user_volume_id_fk", + "tableFrom": "models", + "tableTo": "user_volume", + "columnsFrom": [ + "user_volume_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "subscription_status": { + "name": "subscription_status", + "schema": "comfyui_deploy", + "columns": { + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "subscription_plan", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "subscription_plan_status", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subscription_item_plan_id": { + "name": "subscription_item_plan_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subscription_item_api_id": { + "name": "subscription_item_api_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cancel_at_period_end": { + "name": "cancel_at_period_end", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user_usage": { + "name": "user_usage", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "usage_time": { + "name": "usage_time", + "type": "real", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_usage_user_id_users_id_fk": { + "name": "user_usage_user_id_users_id_fk", + "tableFrom": "user_usage", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user_volume": { + "name": "user_volume", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "volume_name": { + "name": "volume_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_volume_user_id_users_id_fk": { + "name": "user_volume_user_id_users_id_fk", + "tableFrom": "user_volume", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "workflow_run_outputs": { + "name": "workflow_run_outputs", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "run_id": { + "name": "run_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workflow_run_outputs_run_id_workflow_runs_id_fk": { + "name": "workflow_run_outputs_run_id_workflow_runs_id_fk", + "tableFrom": "workflow_run_outputs", + "tableTo": "workflow_runs", + "columnsFrom": [ + "run_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "workflow_runs": { + "name": "workflow_runs", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workflow_version_id": { + "name": "workflow_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "workflow_inputs": { + "name": "workflow_inputs", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "workflow_id": { + "name": "workflow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "machine_id": { + "name": "machine_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "origin": { + "name": "origin", + "type": "workflow_run_origin", + "primaryKey": false, + "notNull": true, + "default": "'api'" + }, + "status": { + "name": "status", + "type": "workflow_run_status", + "primaryKey": false, + "notNull": true, + "default": "'not-started'" + }, + "ended_at": { + "name": "ended_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "queued_at": { + "name": "queued_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "gpu": { + "name": "gpu", + "type": "machine_gpu", + "primaryKey": false, + "notNull": false + }, + "machine_type": { + "name": "machine_type", + "type": "machine_type", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "workflow_runs_workflow_version_id_workflow_versions_id_fk": { + "name": "workflow_runs_workflow_version_id_workflow_versions_id_fk", + "tableFrom": "workflow_runs", + "tableTo": "workflow_versions", + "columnsFrom": [ + "workflow_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workflow_runs_workflow_id_workflows_id_fk": { + "name": "workflow_runs_workflow_id_workflows_id_fk", + "tableFrom": "workflow_runs", + "tableTo": "workflows", + "columnsFrom": [ + "workflow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workflow_runs_machine_id_machines_id_fk": { + "name": "workflow_runs_machine_id_machines_id_fk", + "tableFrom": "workflow_runs", + "tableTo": "machines", + "columnsFrom": [ + "machine_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "workflows": { + "name": "workflows", + "schema": "comfyui_deploy", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "org_id": { + "name": "org_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workflows_user_id_users_id_fk": { + "name": "workflows_user_id_users_id_fk", + "tableFrom": "workflows", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "workflow_versions": { + "name": "workflow_versions", + "schema": "comfyui_deploy", + "columns": { + "workflow_id": { + "name": "workflow_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workflow": { + "name": "workflow", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "workflow_api": { + "name": "workflow_api", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "snapshot": { + "name": "snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workflow_versions_workflow_id_workflows_id_fk": { + "name": "workflow_versions_workflow_id_workflows_id_fk", + "tableFrom": "workflow_versions", + "tableTo": "workflows", + "columnsFrom": [ + "workflow_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "deployment_environment": { + "name": "deployment_environment", + "values": { + "staging": "staging", + "production": "production", + "public-share": "public-share" + } + }, + "machine_gpu": { + "name": "machine_gpu", + "values": { + "T4": "T4", + "A10G": "A10G", + "A100": "A100" + } + }, + "machine_status": { + "name": "machine_status", + "values": { + "ready": "ready", + "building": "building", + "error": "error" + } + }, + "machine_type": { + "name": "machine_type", + "values": { + "classic": "classic", + "runpod-serverless": "runpod-serverless", + "modal-serverless": "modal-serverless", + "comfy-deploy-serverless": "comfy-deploy-serverless" + } + }, + "model_type": { + "name": "model_type", + "values": { + "checkpoint": "checkpoint", + "lora": "lora", + "embedding": "embedding", + "vae": "vae" + } + }, + "model_upload_type": { + "name": "model_upload_type", + "values": { + "civitai": "civitai", + "huggingface": "huggingface", + "other": "other" + } + }, + "resource_upload": { + "name": "resource_upload", + "values": { + "started": "started", + "success": "success", + "failed": "failed" + } + }, + "subscription_plan": { + "name": "subscription_plan", + "values": { + "basic": "basic", + "pro": "pro", + "enterprise": "enterprise" + } + }, + "subscription_plan_status": { + "name": "subscription_plan_status", + "values": { + "active": "active", + "deleted": "deleted", + "paused": "paused" + } + }, + "workflow_run_origin": { + "name": "workflow_run_origin", + "values": { + "manual": "manual", + "api": "api", + "public-share": "public-share" + } + }, + "workflow_run_status": { + "name": "workflow_run_status", + "values": { + "not-started": "not-started", + "running": "running", + "uploading": "uploading", + "success": "success", + "failed": "failed", + "started": "started", + "queued": "queued" + } + } + }, + "schemas": { + "comfyui_deploy": "comfyui_deploy" + }, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + } +} \ No newline at end of file diff --git a/web/drizzle/meta/_journal.json b/web/drizzle/meta/_journal.json index 5786536..6cd6b97 100644 --- a/web/drizzle/meta/_journal.json +++ b/web/drizzle/meta/_journal.json @@ -316,6 +316,13 @@ "when": 1706317908300, "tag": "0044_panoramic_mister_fear", "breakpoints": true + }, + { + "idx": 45, + "version": "5", + "when": 1706336448134, + "tag": "0045_careful_cerise", + "breakpoints": true } ] } \ No newline at end of file diff --git a/web/src/app/(app)/api/update-run/route.ts b/web/src/app/(app)/api/update-run/route.ts index 00dc35d..1dddf8c 100644 --- a/web/src/app/(app)/api/update-run/route.ts +++ b/web/src/app/(app)/api/update-run/route.ts @@ -1,6 +1,7 @@ import { parseDataSafe } from "../../../../lib/parseDataSafe"; import { db } from "@/db/db"; import { + WorkflowRunStatusSchema, userUsageTable, workflowRunOutputs, workflowRunsTable, @@ -14,9 +15,8 @@ import { z } from "zod"; const Request = z.object({ run_id: z.string(), - status: z - .enum(["not-started", "running", "uploading", "success", "failed"]) - .optional(), + status: WorkflowRunStatusSchema.optional(), + time: z.date().optional(), output_data: z.any().optional(), }); @@ -24,9 +24,27 @@ export async function POST(request: Request) { const [data, error] = await parseDataSafe(Request, request); if (!data || error) return error; - const { run_id, status, output_data } = data; + const { run_id, status, time, output_data } = data; - // console.log(run_id, status, output_data); + if (status == "started" && time != undefined) { + // It successfully started, update the started_at time + await db + .update(workflowRunsTable) + .set({ + started_at: time, + }) + .where(eq(workflowRunsTable.id, run_id)); + } + + if (status == "queued" && time != undefined) { + // It successfully started, update the started_at time + await db + .update(workflowRunsTable) + .set({ + queued_at: time, + }) + .where(eq(workflowRunsTable.id, run_id)); + } if (output_data) { const workflow_run_output = await db.insert(workflowRunOutputs).values({ @@ -82,12 +100,6 @@ export async function POST(request: Request) { } } - // const workflow_version = await db.query.workflowVersionTable.findFirst({ - // where: eq(workflowRunsTable.id, workflow_run[0].workflow_version_id), - // }); - - // revalidatePath(`./${workflow_version?.workflow_id}`); - return NextResponse.json( { message: "success", diff --git a/web/src/components/RunDisplay.tsx b/web/src/components/RunDisplay.tsx index e2fa5ed..6446f9b 100644 --- a/web/src/components/RunDisplay.tsx +++ b/web/src/components/RunDisplay.tsx @@ -2,18 +2,18 @@ import { RunInputs } from "@/components/RunInputs"; import { RunOutputs } from "@/components/RunOutputs"; import { Badge } from "@/components/ui/badge"; import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, - DialogTrigger, + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, } from "@/components/ui/dialog"; import { TableCell, TableRow } from "@/components/ui/table"; import { - Tooltip, - TooltipContent, - TooltipTrigger, + Tooltip, + TooltipContent, + TooltipTrigger, } from "@/components/ui/tooltip"; import { getDuration, getRelativeTime } from "@/lib/getRelativeTime"; import { type findAllRuns } from "@/server/findAllRuns"; @@ -21,54 +21,54 @@ import { Suspense } from "react"; import { LiveStatus } from "./LiveStatus"; export async function RunDisplay({ - run, + run, }: { - run: Awaited>[0]; + run: Awaited>[0]; }) { - return ( - - - - {run.number} - - {run.machine?.name} - - - {getRelativeTime(run.created_at)} - - {run.version?.version} - - - {run.origin} - - - - - {getDuration(run.duration)} - -
Cold start: {getDuration(run.cold_start_duration)}
-
Run duration: {getDuration(run.run_duration)}
-
-
-
- -
-
- - - Run outputs - - You can view your run's outputs here - - -
- - - - -
- {/*
{view}
*/} -
-
- ); + return ( + + + + {run.number} + + {run.machine?.name} + + + {getRelativeTime(run.created_at)} + + {run.version?.version} + + + {run.origin} + + + + + {getDuration(run.duration)} + +
Cold start: {getDuration(run.cold_start_duration)}
+
Run duration: {getDuration(run.run_duration)}
+
+
+
+ +
+
+ + + Run outputs + + You can view your run's outputs here + + +
+ + + + +
+ {/*
{view}
*/} +
+
+ ); } diff --git a/web/src/db/schema.ts b/web/src/db/schema.ts index 827953e..693c793 100644 --- a/web/src/db/schema.ts +++ b/web/src/db/schema.ts @@ -93,7 +93,7 @@ export const workflowVersionRelations = relations( fields: [workflowVersionTable.workflow_id], references: [workflowTable.id], }), - }) + }), ); export const workflowRunStatus = pgEnum("workflow_run_status", [ @@ -102,6 +102,8 @@ export const workflowRunStatus = pgEnum("workflow_run_status", [ "uploading", "success", "failed", + "started", + "queued", ]); export const deploymentEnvironment = pgEnum("deployment_environment", [ @@ -116,6 +118,8 @@ export const workflowRunOrigin = pgEnum("workflow_run_origin", [ "public-share", ]); +export const WorkflowRunStatusSchema = z.enum(workflowRunStatus.enumValues); + export const WorkflowRunOriginSchema = z.enum(workflowRunOrigin.enumValues); export type WorkflowRunOriginType = z.infer; @@ -142,7 +146,7 @@ export const workflowRunsTable = dbSchema.table("workflow_runs", { () => workflowVersionTable.id, { onDelete: "set null", - } + }, ), workflow_inputs: jsonb("workflow_inputs").$type>(), @@ -158,7 +162,11 @@ export const workflowRunsTable = dbSchema.table("workflow_runs", { origin: workflowRunOrigin("origin").notNull().default("api"), status: workflowRunStatus("status").notNull().default("not-started"), ended_at: timestamp("ended_at"), + // comfy deploy run created time created_at: timestamp("created_at").defaultNow().notNull(), + // modal gpu cold start begin + queued_at: timestamp("queued_at"), + // modal gpu function actual start time started_at: timestamp("started_at"), gpu: machineGPUOptions("gpu"), machine_type: machinesType("machine_type"), @@ -182,7 +190,7 @@ export const workflowRunRelations = relations( fields: [workflowRunsTable.workflow_id], references: [workflowTable.id], }), - }) + }), ); // We still want to keep the workflow run record. @@ -206,7 +214,7 @@ export const workflowOutputRelations = relations( fields: [workflowRunOutputs.run_id], references: [workflowRunsTable.id], }), - }) + }), ); // when user delete, also delete all the workflow versions @@ -239,7 +247,7 @@ export const snapshotType = z.object({ z.object({ hash: z.string(), disabled: z.boolean(), - }) + }), ), file_custom_nodes: z.array(z.any()), }); @@ -254,7 +262,7 @@ export const showcaseMedia = z.array( z.object({ url: z.string(), isCover: z.boolean().default(false), - }) + }), ); export const showcaseMediaNullable = z @@ -262,7 +270,7 @@ export const showcaseMediaNullable = z z.object({ url: z.string(), isCover: z.boolean().default(false), - }) + }), ) .nullable(); @@ -376,15 +384,10 @@ export const modelUploadType = pgEnum("model_upload_type", [ "other", ]); -// https://www.answeroverflow.com/m/1125106227387584552 -const modelTypes = [ - "checkpoint", - "lora", - "embedding", - "vae", -] as const +// https://www.answeroverflow.com/m/1125106227387584552 +const modelTypes = ["checkpoint", "lora", "embedding", "vae"] as const; export const modelType = pgEnum("model_type", modelTypes); -export type modelEnumType = typeof modelTypes[number] +export type modelEnumType = (typeof modelTypes)[number]; export const modelTable = dbSchema.table("models", { id: uuid("id").primaryKey().defaultRandom().notNull(), @@ -447,16 +450,13 @@ export const modelRelations = relations(modelTable, ({ one }) => ({ }), })); -export const modalVolumeRelations = relations( - userVolume, - ({ many, one }) => ({ - model: many(modelTable), - user: one(usersTable, { - fields: [userVolume.user_id], - references: [usersTable.id], - }), - }) -); +export const modalVolumeRelations = relations(userVolume, ({ many, one }) => ({ + model: many(modelTable), + user: one(usersTable, { + fields: [userVolume.user_id], + references: [usersTable.id], + }), +})); export const subscriptionPlan = pgEnum("subscription_plan", [ "basic", @@ -484,18 +484,15 @@ export const subscriptionStatusTable = dbSchema.table("subscription_status", { updated_at: timestamp("updated_at").defaultNow().notNull(), }); -export const insertCivitaiModelSchema = createInsertSchema( - modelTable, - { - civitai_url: (schema) => - schema.civitai_url - .trim() - .url({ message: "URL required" }) - .includes("civitai.com/models", { - message: "civitai.com/models link required", - }), - } -); +export const insertCivitaiModelSchema = createInsertSchema(modelTable, { + civitai_url: (schema) => + schema.civitai_url + .trim() + .url({ message: "URL required" }) + .includes("civitai.com/models", { + message: "civitai.com/models link required", + }), +}); export type UserType = InferSelectModel; export type WorkflowType = InferSelectModel; @@ -503,7 +500,5 @@ export type MachineType = InferSelectModel; export type WorkflowVersionType = InferSelectModel; export type DeploymentType = InferSelectModel; export type ModelType = InferSelectModel; -export type UserVolumeType = InferSelectModel< - typeof userVolume ->; +export type UserVolumeType = InferSelectModel; export type UserUsageType = InferSelectModel; diff --git a/web/src/server/createRun.ts b/web/src/server/createRun.ts index f8bfe9a..02bbf6e 100644 --- a/web/src/server/createRun.ts +++ b/web/src/server/createRun.ts @@ -229,15 +229,6 @@ export const createRun = withServerPromise( throw e; } - // It successfully started, update the started_at time - - await db - .update(workflowRunsTable) - .set({ - started_at: new Date(), - }) - .where(eq(workflowRunsTable.id, workflow_run[0].id)); - return { workflow_run_id: workflow_run[0].id, message: "Successful workflow run", diff --git a/web/src/server/findAllRuns.tsx b/web/src/server/findAllRuns.tsx index 08bef24..3375847 100644 --- a/web/src/server/findAllRuns.tsx +++ b/web/src/server/findAllRuns.tsx @@ -16,42 +16,40 @@ export async function findAllRuns({ offset = 0, }: RunsSearchTypes) { return await db.query.workflowRunsTable.findMany({ - where: eq(workflowRunsTable.workflow_id, workflow_id), - orderBy: desc(workflowRunsTable.created_at), - offset: offset, - limit: limit, - extras: { - number: sql`row_number() over (order by created_at)`.as( - "number", - ), - total: sql`count(*) over ()`.as("total"), - duration: - sql`(extract(epoch from ended_at) - extract(epoch from created_at))`.as( - "duration", - ), - cold_start_duration: - sql`(extract(epoch from started_at) - extract(epoch from created_at))`.as( - "cold_start_duration", - ), - run_duration: - sql`(extract(epoch from ended_at) - extract(epoch from started_at))`.as( - "run_duration", - ), - }, - with: { - machine: { - columns: { - name: true, - endpoint: true, - }, - }, - version: { - columns: { - version: true, - }, - }, - }, - }); + where: eq(workflowRunsTable.workflow_id, workflow_id), + orderBy: desc(workflowRunsTable.created_at), + offset: offset, + limit: limit, + extras: { + number: sql`row_number() over (order by created_at)`.as("number"), + total: sql`count(*) over ()`.as("total"), + duration: + sql`(extract(epoch from ended_at) - extract(epoch from created_at))`.as( + "duration", + ), + cold_start_duration: + sql`(extract(epoch from started_at) - extract(epoch from queued_at))`.as( + "cold_start_duration", + ), + run_duration: + sql`(extract(epoch from ended_at) - extract(epoch from started_at))`.as( + "run_duration", + ), + }, + with: { + machine: { + columns: { + name: true, + endpoint: true, + }, + }, + version: { + columns: { + version: true, + }, + }, + }, + }); } export async function findAllRunsWithCounts(props: RunsSearchTypes) {