feat: add cold start duration display
This commit is contained in:
parent
1d2497116d
commit
ca1b05fff5
1
web/drizzle/0031_fast_lyja.sql
Normal file
1
web/drizzle/0031_fast_lyja.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE "comfyui_deploy"."workflow_runs" ADD COLUMN "started_at" timestamp;
|
762
web/drizzle/meta/0031_snapshot.json
Normal file
762
web/drizzle/meta/0031_snapshot.json
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
{
|
||||||
|
"id": "1ca4fdb7-c0c4-4c39-8b47-f40282293da0",
|
||||||
|
"prevId": "db06ea66-92c2-4ebe-93c1-6cb8a90ccd8b",
|
||||||
|
"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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
},
|
||||||
|
"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": {}
|
||||||
|
},
|
||||||
|
"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": {}
|
||||||
|
},
|
||||||
|
"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()"
|
||||||
|
},
|
||||||
|
"started_at": {
|
||||||
|
"name": "started_at",
|
||||||
|
"type": "timestamp",
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schemas": {
|
||||||
|
"comfyui_deploy": "comfyui_deploy"
|
||||||
|
},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
}
|
||||||
|
}
|
@ -218,6 +218,13 @@
|
|||||||
"when": 1705716303820,
|
"when": 1705716303820,
|
||||||
"tag": "0030_kind_doorman",
|
"tag": "0030_kind_doorman",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 31,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1705763980972,
|
||||||
|
"tag": "0031_fast_lyja",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -2,62 +2,73 @@ import { RunInputs } from "@/components/RunInputs";
|
|||||||
import { RunOutputs } from "@/components/RunOutputs";
|
import { RunOutputs } from "@/components/RunOutputs";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from "@/components/ui/dialog";
|
} from "@/components/ui/dialog";
|
||||||
import { TableCell, TableRow } from "@/components/ui/table";
|
import { TableCell, TableRow } from "@/components/ui/table";
|
||||||
|
import {
|
||||||
|
Tooltip,
|
||||||
|
TooltipContent,
|
||||||
|
TooltipTrigger,
|
||||||
|
} from "@/components/ui/tooltip";
|
||||||
import { getDuration, getRelativeTime } from "@/lib/getRelativeTime";
|
import { getDuration, getRelativeTime } from "@/lib/getRelativeTime";
|
||||||
import { type findAllRuns } from "@/server/findAllRuns";
|
import { type findAllRuns } from "@/server/findAllRuns";
|
||||||
import { Suspense } from "react";
|
import { Suspense } from "react";
|
||||||
import { LiveStatus } from "./LiveStatus";
|
import { LiveStatus } from "./LiveStatus";
|
||||||
|
|
||||||
export async function RunDisplay({
|
export async function RunDisplay({
|
||||||
run,
|
run,
|
||||||
}: {
|
}: {
|
||||||
run: Awaited<ReturnType<typeof findAllRuns>>[0];
|
run: Awaited<ReturnType<typeof findAllRuns>>[0];
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild className="appearance-none hover:cursor-pointer">
|
<DialogTrigger asChild className="appearance-none hover:cursor-pointer">
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>{run.number}</TableCell>
|
<TableCell>{run.number}</TableCell>
|
||||||
<TableCell className="font-medium truncate">
|
<TableCell className="font-medium truncate">
|
||||||
{run.machine?.name}
|
{run.machine?.name}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="truncate">
|
<TableCell className="truncate">
|
||||||
{getRelativeTime(run.created_at)}
|
{getRelativeTime(run.created_at)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>{run.version?.version}</TableCell>
|
<TableCell>{run.version?.version}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Badge variant="outline" className="truncate">
|
<Badge variant="outline" className="truncate">
|
||||||
{run.origin}
|
{run.origin}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="truncate">
|
<TableCell className="truncate">
|
||||||
{getDuration(run.duration)}
|
<Tooltip>
|
||||||
</TableCell>
|
<TooltipTrigger>{getDuration(run.duration)}</TooltipTrigger>
|
||||||
<LiveStatus run={run} />
|
<TooltipContent>
|
||||||
</TableRow>
|
<div>Cold start: {getDuration(run.cold_start_duration)}</div>
|
||||||
</DialogTrigger>
|
<div>Run duration: {getDuration(run.run_duration)}</div>
|
||||||
<DialogContent className="max-w-3xl">
|
</TooltipContent>
|
||||||
<DialogHeader>
|
</Tooltip>
|
||||||
<DialogTitle>Run outputs</DialogTitle>
|
</TableCell>
|
||||||
<DialogDescription>
|
<LiveStatus run={run} />
|
||||||
You can view your run's outputs here
|
</TableRow>
|
||||||
</DialogDescription>
|
</DialogTrigger>
|
||||||
</DialogHeader>
|
<DialogContent className="max-w-3xl">
|
||||||
<div className="max-h-96 overflow-y-scroll">
|
<DialogHeader>
|
||||||
<RunInputs run={run} />
|
<DialogTitle>Run outputs</DialogTitle>
|
||||||
<Suspense>
|
<DialogDescription>
|
||||||
<RunOutputs run_id={run.id} />
|
You can view your run's outputs here
|
||||||
</Suspense>
|
</DialogDescription>
|
||||||
</div>
|
</DialogHeader>
|
||||||
{/* <div className="max-h-96 overflow-y-scroll">{view}</div> */}
|
<div className="max-h-96 overflow-y-scroll">
|
||||||
</DialogContent>
|
<RunInputs run={run} />
|
||||||
</Dialog>
|
<Suspense>
|
||||||
);
|
<RunOutputs run_id={run.id} />
|
||||||
|
</Suspense>
|
||||||
|
</div>
|
||||||
|
{/* <div className="max-h-96 overflow-y-scroll">{view}</div> */}
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
import {
|
|
||||||
findAllDeployments,
|
|
||||||
findAllRunsWithCounts,
|
|
||||||
} from "../server/findAllRuns";
|
|
||||||
import { DeploymentDisplay } from "./DeploymentDisplay";
|
|
||||||
import { PaginationControl } from "./PaginationControl";
|
|
||||||
import { RunDisplay } from "./RunDisplay";
|
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
@ -15,6 +8,13 @@ import {
|
|||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import { parseAsInteger } from "next-usequerystate";
|
import { parseAsInteger } from "next-usequerystate";
|
||||||
import { headers } from "next/headers";
|
import { headers } from "next/headers";
|
||||||
|
import {
|
||||||
|
findAllDeployments,
|
||||||
|
findAllRunsWithCounts,
|
||||||
|
} from "../server/findAllRuns";
|
||||||
|
import { DeploymentDisplay } from "./DeploymentDisplay";
|
||||||
|
import { PaginationControl } from "./PaginationControl";
|
||||||
|
import { RunDisplay } from "./RunDisplay";
|
||||||
|
|
||||||
const itemPerPage = 6;
|
const itemPerPage = 6;
|
||||||
const pageParser = parseAsInteger.withDefault(1);
|
const pageParser = parseAsInteger.withDefault(1);
|
||||||
@ -33,40 +33,40 @@ export async function RunsTable(props: {
|
|||||||
offset: (page - 1) * itemPerPage,
|
offset: (page - 1) * itemPerPage,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="overflow-auto h-fit w-full">
|
<div className="overflow-auto h-fit w-full">
|
||||||
<Table className="">
|
<Table className="">
|
||||||
{allRuns.length == 0 && (
|
{allRuns.length === 0 && (
|
||||||
<TableCaption>A list of your recent runs.</TableCaption>
|
<TableCaption>A list of your recent runs.</TableCaption>
|
||||||
)}
|
)}
|
||||||
<TableHeader className="bg-background top-0 sticky">
|
<TableHeader className="bg-background top-0 sticky">
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead className="truncate">Number</TableHead>
|
<TableHead className="truncate">Number</TableHead>
|
||||||
<TableHead className="truncate">Machine</TableHead>
|
<TableHead className="truncate">Machine</TableHead>
|
||||||
<TableHead className="truncate">Time</TableHead>
|
<TableHead className="truncate">Time</TableHead>
|
||||||
<TableHead className="truncate">Version</TableHead>
|
<TableHead className="truncate">Version</TableHead>
|
||||||
<TableHead className="truncate">Origin</TableHead>
|
<TableHead className="truncate">Origin</TableHead>
|
||||||
<TableHead className="truncate">Duration</TableHead>
|
<TableHead className="truncate">Duration</TableHead>
|
||||||
<TableHead className="truncate">Live Status</TableHead>
|
<TableHead className="truncate">Live Status</TableHead>
|
||||||
<TableHead className="text-right">Status</TableHead>
|
<TableHead className="text-right">Status</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{allRuns.map((run) => (
|
{allRuns.map((run) => (
|
||||||
<RunDisplay run={run} key={run.id} />
|
<RunDisplay run={run} key={run.id} />
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{Math.ceil(total / itemPerPage) > 0 && (
|
{Math.ceil(total / itemPerPage) > 0 && (
|
||||||
<PaginationControl
|
<PaginationControl
|
||||||
totalPage={Math.ceil(total / itemPerPage)}
|
totalPage={Math.ceil(total / itemPerPage)}
|
||||||
currentPage={page}
|
currentPage={page}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function DeploymentsTable(props: { workflow_id: string }) {
|
export async function DeploymentsTable(props: { workflow_id: string }) {
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { relations, type InferSelectModel } from "drizzle-orm";
|
import { type InferSelectModel, relations } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
text,
|
boolean,
|
||||||
pgSchema,
|
integer,
|
||||||
uuid,
|
jsonb,
|
||||||
integer,
|
pgEnum,
|
||||||
timestamp,
|
pgSchema,
|
||||||
jsonb,
|
text,
|
||||||
pgEnum,
|
timestamp,
|
||||||
boolean,
|
uuid,
|
||||||
} from "drizzle-orm/pg-core";
|
} from "drizzle-orm/pg-core";
|
||||||
import { createInsertSchema } from "drizzle-zod";
|
import { createInsertSchema } from "drizzle-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@ -130,29 +130,30 @@ export const machinesStatus = pgEnum("machine_status", [
|
|||||||
|
|
||||||
// We still want to keep the workflow run record.
|
// We still want to keep the workflow run record.
|
||||||
export const workflowRunsTable = dbSchema.table("workflow_runs", {
|
export const workflowRunsTable = dbSchema.table("workflow_runs", {
|
||||||
id: uuid("id").primaryKey().defaultRandom().notNull(),
|
id: uuid("id").primaryKey().defaultRandom().notNull(),
|
||||||
// when workflow version deleted, still want to keep this record
|
// when workflow version deleted, still want to keep this record
|
||||||
workflow_version_id: uuid("workflow_version_id").references(
|
workflow_version_id: uuid("workflow_version_id").references(
|
||||||
() => workflowVersionTable.id,
|
() => workflowVersionTable.id,
|
||||||
{
|
{
|
||||||
onDelete: "set null",
|
onDelete: "set null",
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
workflow_inputs:
|
workflow_inputs:
|
||||||
jsonb("workflow_inputs").$type<Record<string, string | number>>(),
|
jsonb("workflow_inputs").$type<Record<string, string | number>>(),
|
||||||
workflow_id: uuid("workflow_id")
|
workflow_id: uuid("workflow_id")
|
||||||
.notNull()
|
.notNull()
|
||||||
.references(() => workflowTable.id, {
|
.references(() => workflowTable.id, {
|
||||||
onDelete: "cascade",
|
onDelete: "cascade",
|
||||||
}),
|
}),
|
||||||
// when machine deleted, still want to keep this record
|
// when machine deleted, still want to keep this record
|
||||||
machine_id: uuid("machine_id").references(() => machinesTable.id, {
|
machine_id: uuid("machine_id").references(() => machinesTable.id, {
|
||||||
onDelete: "set null",
|
onDelete: "set null",
|
||||||
}),
|
}),
|
||||||
origin: workflowRunOrigin("origin").notNull().default("api"),
|
origin: workflowRunOrigin("origin").notNull().default("api"),
|
||||||
status: workflowRunStatus("status").notNull().default("not-started"),
|
status: workflowRunStatus("status").notNull().default("not-started"),
|
||||||
ended_at: timestamp("ended_at"),
|
ended_at: timestamp("ended_at"),
|
||||||
created_at: timestamp("created_at").defaultNow().notNull(),
|
created_at: timestamp("created_at").defaultNow().notNull(),
|
||||||
|
started_at: timestamp("started_at"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const workflowRunRelations = relations(
|
export const workflowRunRelations = relations(
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
"use server";
|
"use server";
|
||||||
|
|
||||||
import { withServerPromise } from "./withServerPromise";
|
|
||||||
import { db } from "@/db/db";
|
import { db } from "@/db/db";
|
||||||
import type {
|
import type {
|
||||||
MachineType,
|
MachineType,
|
||||||
WorkflowRunOriginType,
|
WorkflowRunOriginType,
|
||||||
WorkflowVersionType,
|
WorkflowVersionType,
|
||||||
} from "@/db/schema";
|
} from "@/db/schema";
|
||||||
import { machinesTable, workflowRunsTable } from "@/db/schema";
|
import { machinesTable, workflowRunsTable } from "@/db/schema";
|
||||||
import type { APIKeyUserType } from "@/server/APIKeyBodyRequest";
|
import type { APIKeyUserType } from "@/server/APIKeyBodyRequest";
|
||||||
@ -16,219 +15,229 @@ import { and, eq } from "drizzle-orm";
|
|||||||
import { revalidatePath } from "next/cache";
|
import { revalidatePath } from "next/cache";
|
||||||
import "server-only";
|
import "server-only";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
|
import { withServerPromise } from "./withServerPromise";
|
||||||
|
|
||||||
export const createRun = withServerPromise(
|
export const createRun = withServerPromise(
|
||||||
async ({
|
async ({
|
||||||
origin,
|
origin,
|
||||||
workflow_version_id,
|
workflow_version_id,
|
||||||
machine_id,
|
machine_id,
|
||||||
inputs,
|
inputs,
|
||||||
runOrigin,
|
runOrigin,
|
||||||
apiUser,
|
apiUser,
|
||||||
}: {
|
}: {
|
||||||
origin: string;
|
origin: string;
|
||||||
workflow_version_id: string | WorkflowVersionType;
|
workflow_version_id: string | WorkflowVersionType;
|
||||||
machine_id: string | MachineType;
|
machine_id: string | MachineType;
|
||||||
inputs?: Record<string, string | number>;
|
inputs?: Record<string, string | number>;
|
||||||
runOrigin?: WorkflowRunOriginType;
|
runOrigin?: WorkflowRunOriginType;
|
||||||
apiUser?: APIKeyUserType;
|
apiUser?: APIKeyUserType;
|
||||||
}) => {
|
}) => {
|
||||||
const machine =
|
const machine =
|
||||||
typeof machine_id === "string"
|
typeof machine_id === "string"
|
||||||
? await db.query.machinesTable.findFirst({
|
? await db.query.machinesTable.findFirst({
|
||||||
where: and(
|
where: and(
|
||||||
eq(machinesTable.id, machine_id),
|
eq(machinesTable.id, machine_id),
|
||||||
eq(machinesTable.disabled, false)
|
eq(machinesTable.disabled, false),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
: machine_id;
|
: machine_id;
|
||||||
|
|
||||||
if (!machine) {
|
if (!machine) {
|
||||||
throw new Error("Machine not found");
|
throw new Error("Machine not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const workflow_version_data =
|
const workflow_version_data =
|
||||||
typeof workflow_version_id === "string"
|
typeof workflow_version_id === "string"
|
||||||
? await db.query.workflowVersionTable.findFirst({
|
? await db.query.workflowVersionTable.findFirst({
|
||||||
where: eq(workflowRunsTable.id, workflow_version_id),
|
where: eq(workflowRunsTable.id, workflow_version_id),
|
||||||
with: {
|
with: {
|
||||||
workflow: {
|
workflow: {
|
||||||
columns: {
|
columns: {
|
||||||
org_id: true,
|
org_id: true,
|
||||||
user_id: true,
|
user_id: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
: workflow_version_id;
|
: workflow_version_id;
|
||||||
|
|
||||||
if (!workflow_version_data) {
|
if (!workflow_version_data) {
|
||||||
throw new Error("Workflow version not found");
|
throw new Error("Workflow version not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiUser)
|
if (apiUser)
|
||||||
if (apiUser.org_id) {
|
if (apiUser.org_id) {
|
||||||
// is org api call, check org only
|
// is org api call, check org only
|
||||||
if (apiUser.org_id != workflow_version_data.workflow.org_id) {
|
if (apiUser.org_id != workflow_version_data.workflow.org_id) {
|
||||||
throw new Error("Workflow not found");
|
throw new Error("Workflow not found");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// is user api call, check user only
|
// is user api call, check user only
|
||||||
if (
|
if (
|
||||||
apiUser.user_id != workflow_version_data.workflow.user_id &&
|
apiUser.user_id != workflow_version_data.workflow.user_id &&
|
||||||
workflow_version_data.workflow.org_id == null
|
workflow_version_data.workflow.org_id == null
|
||||||
) {
|
) {
|
||||||
throw new Error("Workflow not found");
|
throw new Error("Workflow not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const workflow_api = workflow_version_data.workflow_api;
|
const workflow_api = workflow_version_data.workflow_api;
|
||||||
|
|
||||||
// Replace the inputs
|
// Replace the inputs
|
||||||
if (inputs && workflow_api) {
|
if (inputs && workflow_api) {
|
||||||
for (const key in inputs) {
|
for (const key in inputs) {
|
||||||
Object.entries(workflow_api).forEach(([_, node]) => {
|
Object.entries(workflow_api).forEach(([_, node]) => {
|
||||||
if (node.inputs["input_id"] === key) {
|
if (node.inputs["input_id"] === key) {
|
||||||
node.inputs["input_id"] = inputs[key];
|
node.inputs["input_id"] = inputs[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let prompt_id: string | undefined = undefined;
|
let prompt_id: string | undefined = undefined;
|
||||||
const shareData = {
|
const shareData = {
|
||||||
workflow_api: workflow_api,
|
workflow_api: workflow_api,
|
||||||
status_endpoint: `${origin}/api/update-run`,
|
status_endpoint: `${origin}/api/update-run`,
|
||||||
file_upload_endpoint: `${origin}/api/file-upload`,
|
file_upload_endpoint: `${origin}/api/file-upload`,
|
||||||
};
|
};
|
||||||
|
|
||||||
prompt_id = v4();
|
prompt_id = v4();
|
||||||
|
|
||||||
// Add to our db
|
// Add to our db
|
||||||
const workflow_run = await db
|
const workflow_run = await db
|
||||||
.insert(workflowRunsTable)
|
.insert(workflowRunsTable)
|
||||||
.values({
|
.values({
|
||||||
id: prompt_id,
|
id: prompt_id,
|
||||||
workflow_id: workflow_version_data.workflow_id,
|
workflow_id: workflow_version_data.workflow_id,
|
||||||
workflow_version_id: workflow_version_data.id,
|
workflow_version_id: workflow_version_data.id,
|
||||||
workflow_inputs: inputs,
|
workflow_inputs: inputs,
|
||||||
machine_id: machine.id,
|
machine_id: machine.id,
|
||||||
origin: runOrigin,
|
origin: runOrigin,
|
||||||
})
|
})
|
||||||
.returning();
|
.returning();
|
||||||
|
|
||||||
revalidatePath(`/${workflow_version_data.workflow_id}`);
|
revalidatePath(`/${workflow_version_data.workflow_id}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (machine.type) {
|
switch (machine.type) {
|
||||||
case "comfy-deploy-serverless":
|
case "comfy-deploy-serverless":
|
||||||
case "modal-serverless":
|
case "modal-serverless":
|
||||||
const _data = {
|
const _data = {
|
||||||
input: {
|
input: {
|
||||||
...shareData,
|
...shareData,
|
||||||
prompt_id: prompt_id,
|
prompt_id: prompt_id,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const ___result = await fetch(`${machine.endpoint}/run`, {
|
const ___result = await fetch(`${machine.endpoint}/run`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(_data),
|
body: JSON.stringify(_data),
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
});
|
});
|
||||||
console.log(___result);
|
console.log(___result);
|
||||||
if (!___result.ok)
|
if (!___result.ok)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Error creating run, ${
|
`Error creating run, ${
|
||||||
___result.statusText
|
___result.statusText
|
||||||
} ${await ___result.text()}`
|
} ${await ___result.text()}`,
|
||||||
);
|
);
|
||||||
console.log(_data, ___result);
|
console.log(_data, ___result);
|
||||||
break;
|
break;
|
||||||
case "runpod-serverless":
|
case "runpod-serverless":
|
||||||
const data = {
|
const data = {
|
||||||
input: {
|
input: {
|
||||||
...shareData,
|
...shareData,
|
||||||
prompt_id: prompt_id,
|
prompt_id: prompt_id,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!machine.auth_token &&
|
!machine.auth_token &&
|
||||||
!machine.endpoint.includes("localhost") &&
|
!machine.endpoint.includes("localhost") &&
|
||||||
!machine.endpoint.includes("127.0.0.1")
|
!machine.endpoint.includes("127.0.0.1")
|
||||||
) {
|
) {
|
||||||
throw new Error("Machine auth token not found");
|
throw new Error("Machine auth token not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const __result = await fetch(`${machine.endpoint}/run`, {
|
const __result = await fetch(`${machine.endpoint}/run`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: `Bearer ${machine.auth_token}`,
|
Authorization: `Bearer ${machine.auth_token}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
});
|
});
|
||||||
console.log(__result);
|
console.log(__result);
|
||||||
if (!__result.ok)
|
if (!__result.ok)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Error creating run, ${
|
`Error creating run, ${
|
||||||
__result.statusText
|
__result.statusText
|
||||||
} ${await __result.text()}`
|
} ${await __result.text()}`,
|
||||||
);
|
);
|
||||||
console.log(data, __result);
|
console.log(data, __result);
|
||||||
break;
|
break;
|
||||||
case "classic":
|
case "classic":
|
||||||
const body = {
|
const body = {
|
||||||
...shareData,
|
...shareData,
|
||||||
prompt_id: prompt_id,
|
prompt_id: prompt_id,
|
||||||
};
|
};
|
||||||
// console.log(body);
|
// console.log(body);
|
||||||
const comfyui_endpoint = `${machine.endpoint}/comfyui-deploy/run`;
|
const comfyui_endpoint = `${machine.endpoint}/comfyui-deploy/run`;
|
||||||
const _result = await fetch(comfyui_endpoint, {
|
const _result = await fetch(comfyui_endpoint, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
cache: "no-store",
|
cache: "no-store",
|
||||||
});
|
});
|
||||||
// console.log(_result);
|
// console.log(_result);
|
||||||
|
|
||||||
if (!_result.ok) {
|
if (!_result.ok) {
|
||||||
let message = `Error creating run, ${_result.statusText}`;
|
let message = `Error creating run, ${_result.statusText}`;
|
||||||
try {
|
try {
|
||||||
const result = await ComfyAPI_Run.parseAsync(
|
const result = await ComfyAPI_Run.parseAsync(
|
||||||
await _result.json()
|
await _result.json(),
|
||||||
);
|
);
|
||||||
message += ` ${result.node_errors}`;
|
message += ` ${result.node_errors}`;
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
// prompt_id = result.prompt_id;
|
// prompt_id = result.prompt_id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
await db
|
await db
|
||||||
.update(workflowRunsTable)
|
.update(workflowRunsTable)
|
||||||
.set({
|
.set({
|
||||||
status: "failed",
|
status: "failed",
|
||||||
})
|
})
|
||||||
.where(eq(workflowRunsTable.id, workflow_run[0].id));
|
.where(eq(workflowRunsTable.id, workflow_run[0].id));
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
// It successfully started, update the started_at time
|
||||||
workflow_run_id: workflow_run[0].id,
|
|
||||||
message: "Successful workflow run",
|
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",
|
||||||
|
};
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export async function checkStatus(run_id: string) {
|
export async function checkStatus(run_id: string) {
|
||||||
const { userId } = auth();
|
const { userId } = auth();
|
||||||
if (!userId) throw new Error("User not found");
|
if (!userId) throw new Error("User not found");
|
||||||
|
|
||||||
return await getRunsData(run_id);
|
return await getRunsData(run_id);
|
||||||
}
|
}
|
||||||
|
@ -16,32 +16,42 @@ export async function findAllRuns({
|
|||||||
offset = 0,
|
offset = 0,
|
||||||
}: RunsSearchTypes) {
|
}: RunsSearchTypes) {
|
||||||
return await db.query.workflowRunsTable.findMany({
|
return await db.query.workflowRunsTable.findMany({
|
||||||
where: eq(workflowRunsTable.workflow_id, workflow_id),
|
where: eq(workflowRunsTable.workflow_id, workflow_id),
|
||||||
orderBy: desc(workflowRunsTable.created_at),
|
orderBy: desc(workflowRunsTable.created_at),
|
||||||
offset: offset,
|
offset: offset,
|
||||||
limit: limit,
|
limit: limit,
|
||||||
extras: {
|
extras: {
|
||||||
number: sql<number>`row_number() over (order by created_at)`.as("number"),
|
number: sql<number>`row_number() over (order by created_at)`.as(
|
||||||
total: sql<number>`count(*) over ()`.as("total"),
|
"number",
|
||||||
duration:
|
),
|
||||||
sql<number>`(extract(epoch from ended_at) - extract(epoch from created_at))`.as(
|
total: sql<number>`count(*) over ()`.as("total"),
|
||||||
"duration"
|
duration:
|
||||||
),
|
sql<number>`(extract(epoch from ended_at) - extract(epoch from created_at))`.as(
|
||||||
},
|
"duration",
|
||||||
with: {
|
),
|
||||||
machine: {
|
cold_start_duration:
|
||||||
columns: {
|
sql<number>`(extract(epoch from started_at) - extract(epoch from created_at))`.as(
|
||||||
name: true,
|
"cold_start_duration",
|
||||||
endpoint: true,
|
),
|
||||||
},
|
run_duration:
|
||||||
},
|
sql<number>`(extract(epoch from ended_at) - extract(epoch from started_at))`.as(
|
||||||
version: {
|
"run_duration",
|
||||||
columns: {
|
),
|
||||||
version: true,
|
},
|
||||||
},
|
with: {
|
||||||
},
|
machine: {
|
||||||
},
|
columns: {
|
||||||
});
|
name: true,
|
||||||
|
endpoint: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
version: {
|
||||||
|
columns: {
|
||||||
|
version: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findAllRunsWithCounts(props: RunsSearchTypes) {
|
export async function findAllRunsWithCounts(props: RunsSearchTypes) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user