From bf206515e8653bbe431e106277b72082e0c9e388 Mon Sep 17 00:00:00 2001 From: Lucas Abel <22837557+uael@users.noreply.github.com> Date: Wed, 12 Feb 2025 16:34:03 +0100 Subject: [PATCH] fix(backend): improve schedule queries plan to leverage indices better for performance (#5273) * backend: fix schedule queries plan * rework * fix skipped as non success * update sqlx * update * all * fix npm run check --------- Co-authored-by: Ruben Fiszel --- ...3fad4878f48db8c17c6d58590bd5df2e3350a.json | 24 - ...4210d39f405016ffec374e4b15a2528baccb5.json | 198 ------- ...34bbabdd8703bfdf4d43df2c65e50d4ca2c85.json | 40 -- ...4c9f769ffe5004871a049e4232e0092532062.json | 25 + ...36c93f43dec5df570f869580056702b7d1e09.json | 118 ----- ...53afc1f1ad354599de11ebc6e256b58543265.json | 12 + ...5708dcc4811857b7e5631f0decf5d75ef3aa3.json | 30 ++ ...15251f0b32afa2445401170d931e0fe1febb8.json | 119 ----- ...97dfd5eeda5977a8746be77c8aa65a7ec299e.json | 12 + ...e3935e9d57be68a1811ffdee904a5f56e7023.json | 118 ----- ...7a47667b6f9f3dc0d51987cce159433459ab0.json | 12 + ...d964fda13a1091a8206ee174ed3a161248126.json | 25 + ...8c6395e2440ea27553b7ccb18d7149b106728.json | 12 + ...89569fe5666e36ca2650dabd9b494dc30f435.json | 12 + ...044812f8103498080a24246063e06b0ebfccf.json | 106 ---- ...2a540f1d147948e1b1a7523b21151ffa22305.json | 38 -- ...fe682b023d1868a182b7cac16ce799433c257.json | 25 - ...b1bf1f70e17486a9d315db130852d5e325200.json | 12 + ...6f8377ec190669e2e22f8d511871d6fbe07b8.json | 38 -- ...97d0a03f6c26f0b14fc92900f7600e70a7a8b.json | 26 + ...dde4395ab6ef1181237a886fa398dcfa0b589.json | 130 ----- ...a6854a34a99d2bf107feaafc499588f7330a0.json | 12 + ...587d8cad3b67d4dfa9de52777d4ea9490b6b7.json | 15 - ...2529d57faf5e77f6792d5bda608ff9658d7c9.json | 24 - ...4efe29311aabfba6e09efa10bab6a551d658b.json | 16 - ...1717ffa5e01250020cfb24e4bad276397dee2.json | 106 ---- ...aabefe718829fb6eae2f681c4c8328acc94b2.json | 46 -- ...cb3c037309f09e84acbb7945a0466d6e9f576.json | 12 + ...bd41c7b823186ac056a0a676da85dc5d9a027.json | 24 - ...cf0b385bff14faab495e049f2029790f76d25.json | 12 + ...80e111a159a749728ce5363100cf883bdf02a.json | 12 + ...09b246b6f84e49c659bc8e2c7b66cfec6d976.json | 38 ++ ...34b976cbe0280e7215862aaf5ef445663793d.json | 12 + ...f3741b9782d8e2d4b6ff6c104fdcac5f58323.json | 12 + ...b6a09259fedca329d790c34e58703bf26f34c.json | 64 --- ...2c86a69b7b7378333322a57856f8e43c6cd77.json | 12 + ...50205131517_v2_skipped_is_success.down.sql | 1 + ...0250205131517_v2_skipped_is_success.up.sql | 42 ++ backend/windmill-api/src/db.rs | 75 +++ backend/windmill-api/src/schedule.rs | 71 +-- backend/windmill-queue/src/jobs.rs | 31 +- backend/windmill-queue/src/schedule.rs | 18 +- backend/windmill-worker/src/common.rs | 3 +- backend/windmill-worker/src/worker_flow.rs | 19 +- .../apps/editor/SubGridEditor.svelte | 2 +- .../(root)/(logged)/schedules/+page.svelte | 495 +++++++++--------- 46 files changed, 757 insertions(+), 1549 deletions(-) delete mode 100644 backend/.sqlx/query-01e92a4ba3074f1dce6ec98bc6c3fad4878f48db8c17c6d58590bd5df2e3350a.json delete mode 100644 backend/.sqlx/query-099894523449a70eb301ecd1d744210d39f405016ffec374e4b15a2528baccb5.json delete mode 100644 backend/.sqlx/query-199a76c04e3f0891ad09af27b9534bbabdd8703bfdf4d43df2c65e50d4ca2c85.json create mode 100644 backend/.sqlx/query-3a47d8ec0f4ba1644951f0c88504c9f769ffe5004871a049e4232e0092532062.json delete mode 100644 backend/.sqlx/query-3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09.json create mode 100644 backend/.sqlx/query-42177e249794a4b7b945b93efd853afc1f1ad354599de11ebc6e256b58543265.json create mode 100644 backend/.sqlx/query-430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3.json delete mode 100644 backend/.sqlx/query-4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8.json create mode 100644 backend/.sqlx/query-4d3bbcc029ec0926bf97de4b5ef97dfd5eeda5977a8746be77c8aa65a7ec299e.json delete mode 100644 backend/.sqlx/query-59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023.json create mode 100644 backend/.sqlx/query-608393951c85d9e721b506d2f6a7a47667b6f9f3dc0d51987cce159433459ab0.json create mode 100644 backend/.sqlx/query-6513c1433dbfe03f7c778963a05d964fda13a1091a8206ee174ed3a161248126.json create mode 100644 backend/.sqlx/query-6536214f31e9d600e868b01385d8c6395e2440ea27553b7ccb18d7149b106728.json create mode 100644 backend/.sqlx/query-74754b03304a69391d61560848e89569fe5666e36ca2650dabd9b494dc30f435.json delete mode 100644 backend/.sqlx/query-7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf.json delete mode 100644 backend/.sqlx/query-830297547ea33969f96a5c4c2b82a540f1d147948e1b1a7523b21151ffa22305.json delete mode 100644 backend/.sqlx/query-833a4ecec12dfe67f28016a135ffe682b023d1868a182b7cac16ce799433c257.json create mode 100644 backend/.sqlx/query-85181656012b18cd26998128c30b1bf1f70e17486a9d315db130852d5e325200.json delete mode 100644 backend/.sqlx/query-86cc1e3c18e936a700d8842a51a6f8377ec190669e2e22f8d511871d6fbe07b8.json create mode 100644 backend/.sqlx/query-910b9b8afb3df5e437e43ff4adc97d0a03f6c26f0b14fc92900f7600e70a7a8b.json delete mode 100644 backend/.sqlx/query-91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589.json create mode 100644 backend/.sqlx/query-93586f1ffc7b8dbe62b21a21acfa6854a34a99d2bf107feaafc499588f7330a0.json delete mode 100644 backend/.sqlx/query-95e420b60fba20b36b2c6675998587d8cad3b67d4dfa9de52777d4ea9490b6b7.json delete mode 100644 backend/.sqlx/query-9e7e6fe1dfba032e586f64531e12529d57faf5e77f6792d5bda608ff9658d7c9.json delete mode 100644 backend/.sqlx/query-a6c168c60bc8c42f70b18565e824efe29311aabfba6e09efa10bab6a551d658b.json delete mode 100644 backend/.sqlx/query-a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2.json delete mode 100644 backend/.sqlx/query-ca5f42cb0e368d0817461600152aabefe718829fb6eae2f681c4c8328acc94b2.json create mode 100644 backend/.sqlx/query-cb5a8545ea140ed69c7b70d8c08cb3c037309f09e84acbb7945a0466d6e9f576.json delete mode 100644 backend/.sqlx/query-d6c8f4e49cf7b6db5c979c88e02bd41c7b823186ac056a0a676da85dc5d9a027.json create mode 100644 backend/.sqlx/query-d949e8b91fbdf4c50c1c2cbc608cf0b385bff14faab495e049f2029790f76d25.json create mode 100644 backend/.sqlx/query-e00144305b880cca3994b53c4a080e111a159a749728ce5363100cf883bdf02a.json create mode 100644 backend/.sqlx/query-e6a8ddfd74ebab55ede5989fd7d09b246b6f84e49c659bc8e2c7b66cfec6d976.json create mode 100644 backend/.sqlx/query-e9038a6fcfd8bdf4855c5919ce634b976cbe0280e7215862aaf5ef445663793d.json create mode 100644 backend/.sqlx/query-ebfd39f168722701fb63cd37aaef3741b9782d8e2d4b6ff6c104fdcac5f58323.json delete mode 100644 backend/.sqlx/query-f96dd1dd944506c07ad58d178e9b6a09259fedca329d790c34e58703bf26f34c.json create mode 100644 backend/.sqlx/query-fa94a9ee5514f6808d3813394e62c86a69b7b7378333322a57856f8e43c6cd77.json create mode 100644 backend/migrations/20250205131517_v2_skipped_is_success.down.sql create mode 100644 backend/migrations/20250205131517_v2_skipped_is_success.up.sql diff --git a/backend/.sqlx/query-01e92a4ba3074f1dce6ec98bc6c3fad4878f48db8c17c6d58590bd5df2e3350a.json b/backend/.sqlx/query-01e92a4ba3074f1dce6ec98bc6c3fad4878f48db8c17c6d58590bd5df2e3350a.json deleted file mode 100644 index a6f202a16f..0000000000 --- a/backend/.sqlx/query-01e92a4ba3074f1dce6ec98bc6c3fad4878f48db8c17c6d58590bd5df2e3350a.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n UPDATE postgres_trigger \n SET \n server_id = $1, \n last_server_ping = now(),\n error = 'Connecting...'\n WHERE \n enabled IS TRUE \n AND workspace_id = $2 \n AND path = $3 \n AND (last_server_ping IS NULL \n OR last_server_ping < now() - INTERVAL '15 seconds'\n ) \n RETURNING true\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "?column?", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Varchar", - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "01e92a4ba3074f1dce6ec98bc6c3fad4878f48db8c17c6d58590bd5df2e3350a" -} diff --git a/backend/.sqlx/query-099894523449a70eb301ecd1d744210d39f405016ffec374e4b15a2528baccb5.json b/backend/.sqlx/query-099894523449a70eb301ecd1d744210d39f405016ffec374e4b15a2528baccb5.json deleted file mode 100644 index 8a4a9b9c20..0000000000 --- a/backend/.sqlx/query-099894523449a70eb301ecd1d744210d39f405016ffec374e4b15a2528baccb5.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT schedule.*, t.jobs FROM schedule, LATERAL ( SELECT ARRAY (SELECT json_build_object('id', id, 'success', success, 'duration_ms', duration_ms) FROM v2_as_completed_job WHERE\n v2_as_completed_job.schedule_path = schedule.path AND v2_as_completed_job.workspace_id = $1 AND parent_job IS NULL AND is_skipped = False ORDER BY started_at DESC LIMIT 20) AS jobs ) t\n WHERE schedule.workspace_id = $1 ORDER BY schedule.edited_at desc LIMIT $2 OFFSET $3", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 4, - "name": "schedule", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "enabled", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "args", - "type_info": "Jsonb" - }, - { - "ordinal": 8, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 9, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 10, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 11, - "name": "error", - "type_info": "Text" - }, - { - "ordinal": 12, - "name": "timezone", - "type_info": "Varchar" - }, - { - "ordinal": 13, - "name": "on_failure", - "type_info": "Varchar" - }, - { - "ordinal": 14, - "name": "on_recovery", - "type_info": "Varchar" - }, - { - "ordinal": 15, - "name": "on_failure_times", - "type_info": "Int4" - }, - { - "ordinal": 16, - "name": "on_failure_exact", - "type_info": "Bool" - }, - { - "ordinal": 17, - "name": "on_failure_extra_args", - "type_info": "Json" - }, - { - "ordinal": 18, - "name": "on_recovery_times", - "type_info": "Int4" - }, - { - "ordinal": 19, - "name": "on_recovery_extra_args", - "type_info": "Json" - }, - { - "ordinal": 20, - "name": "ws_error_handler_muted", - "type_info": "Bool" - }, - { - "ordinal": 21, - "name": "retry", - "type_info": "Jsonb" - }, - { - "ordinal": 22, - "name": "summary", - "type_info": "Varchar" - }, - { - "ordinal": 23, - "name": "no_flow_overlap", - "type_info": "Bool" - }, - { - "ordinal": 24, - "name": "tag", - "type_info": "Varchar" - }, - { - "ordinal": 25, - "name": "paused_until", - "type_info": "Timestamptz" - }, - { - "ordinal": 26, - "name": "on_success", - "type_info": "Varchar" - }, - { - "ordinal": 27, - "name": "on_success_extra_args", - "type_info": "Json" - }, - { - "ordinal": 28, - "name": "cron_version", - "type_info": "Text" - }, - { - "ordinal": 29, - "name": "jobs", - "type_info": "JsonArray" - } - ], - "parameters": { - "Left": [ - "Text", - "Int8", - "Int8" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - false, - false, - false, - true, - false, - true, - true, - true, - true, - true, - true, - true, - false, - true, - true, - false, - true, - true, - true, - true, - true, - null - ] - }, - "hash": "099894523449a70eb301ecd1d744210d39f405016ffec374e4b15a2528baccb5" -} diff --git a/backend/.sqlx/query-199a76c04e3f0891ad09af27b9534bbabdd8703bfdf4d43df2c65e50d4ca2c85.json b/backend/.sqlx/query-199a76c04e3f0891ad09af27b9534bbabdd8703bfdf4d43df2c65e50d4ca2c85.json deleted file mode 100644 index 7dfa56ad40..0000000000 --- a/backend/.sqlx/query-199a76c04e3f0891ad09af27b9534bbabdd8703bfdf4d43df2c65e50d4ca2c85.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n schemaname AS schema_name,\n tablename AS table_name,\n attnames AS columns,\n rowfilter AS where_clause\n FROM\n pg_publication_tables\n WHERE\n pubname = $1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "schema_name", - "type_info": "Name" - }, - { - "ordinal": 1, - "name": "table_name", - "type_info": "Name" - }, - { - "ordinal": 2, - "name": "columns", - "type_info": "NameArray" - }, - { - "ordinal": 3, - "name": "where_clause", - "type_info": "Text" - } - ], - "parameters": { - "Left": [ - "Name" - ] - }, - "nullable": [ - true, - true, - true, - true - ] - }, - "hash": "199a76c04e3f0891ad09af27b9534bbabdd8703bfdf4d43df2c65e50d4ca2c85" -} diff --git a/backend/.sqlx/query-3a47d8ec0f4ba1644951f0c88504c9f769ffe5004871a049e4232e0092532062.json b/backend/.sqlx/query-3a47d8ec0f4ba1644951f0c88504c9f769ffe5004871a049e4232e0092532062.json new file mode 100644 index 0000000000..a07fcd57db --- /dev/null +++ b/backend/.sqlx/query-3a47d8ec0f4ba1644951f0c88504c9f769ffe5004871a049e4232e0092532062.json @@ -0,0 +1,25 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT EXISTS (\n SELECT 1 FROM v2_job j JOIN v2_job_queue USING (id)\n WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2 AND runnable_path = $4\n AND parent_job IS NULL\n AND scheduled_for = $3\n )", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "exists", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Timestamptz", + "Text" + ] + }, + "nullable": [ + null + ] + }, + "hash": "3a47d8ec0f4ba1644951f0c88504c9f769ffe5004871a049e4232e0092532062" +} diff --git a/backend/.sqlx/query-3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09.json b/backend/.sqlx/query-3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09.json deleted file mode 100644 index 4356a016c0..0000000000 --- a/backend/.sqlx/query-3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT workspace_id, path, url, script_path, is_flow, edited_by, email, edited_at, server_id, last_server_ping, extra_perms, error, enabled, filters as \"filters: _\", initial_messages as \"initial_messages: _\", url_runnable_args as \"url_runnable_args: _\", can_return_message FROM websocket_trigger\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "url", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 5, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 6, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 8, - "name": "server_id", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "last_server_ping", - "type_info": "Timestamptz" - }, - { - "ordinal": 10, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 11, - "name": "error", - "type_info": "Text" - }, - { - "ordinal": 12, - "name": "enabled", - "type_info": "Bool" - }, - { - "ordinal": 13, - "name": "filters: _", - "type_info": "JsonbArray" - }, - { - "ordinal": 14, - "name": "initial_messages: _", - "type_info": "JsonbArray" - }, - { - "ordinal": 15, - "name": "url_runnable_args: _", - "type_info": "Jsonb" - }, - { - "ordinal": 16, - "name": "can_return_message", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false, - true, - true, - false, - true, - false, - false, - true, - true, - false - ] - }, - "hash": "3d0f036a3176dcc787bef3f10a336c93f43dec5df570f869580056702b7d1e09" -} diff --git a/backend/.sqlx/query-42177e249794a4b7b945b93efd853afc1f1ad354599de11ebc6e256b58543265.json b/backend/.sqlx/query-42177e249794a4b7b945b93efd853afc1f1ad354599de11ebc6e256b58543265.json new file mode 100644 index 0000000000..71171ad831 --- /dev/null +++ b/backend/.sqlx/query-42177e249794a4b7b945b93efd853afc1f1ad354599de11ebc6e256b58543265.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_6", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "42177e249794a4b7b945b93efd853afc1f1ad354599de11ebc6e256b58543265" +} diff --git a/backend/.sqlx/query-430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3.json b/backend/.sqlx/query-430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3.json new file mode 100644 index 0000000000..660b5cb402 --- /dev/null +++ b/backend/.sqlx/query-430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3.json @@ -0,0 +1,30 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n schedule.path, t.jobs FROM schedule,\n LATERAL(SELECT ARRAY(\n SELECT json_build_object('id', id, 'success', status = 'success', 'duration_ms', duration_ms)\n FROM v2_job_completed c JOIN v2_job j USING (id)\n WHERE trigger_kind = 'schedule'\n AND trigger = schedule.path\n AND c.workspace_id = $1\n AND j.workspace_id = $1\n AND parent_job IS NULL AND runnable_path = schedule.script_path\n AND status <> 'skipped'\n ORDER BY created_at DESC\n LIMIT 20\n ) AS jobs) t\n WHERE workspace_id = $1\n ORDER BY edited_at DESC\n LIMIT $2 OFFSET $3", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "path", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "jobs", + "type_info": "JsonArray" + } + ], + "parameters": { + "Left": [ + "Text", + "Int8", + "Int8" + ] + }, + "nullable": [ + false, + null + ] + }, + "hash": "430ea56dea72c7d326735952bf85708dcc4811857b7e5631f0decf5d75ef3aa3" +} diff --git a/backend/.sqlx/query-4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8.json b/backend/.sqlx/query-4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8.json deleted file mode 100644 index d2648d4230..0000000000 --- a/backend/.sqlx/query-4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT workspace_id, path, route_path, route_path_key, script_path, is_flow, edited_by, edited_at, email, extra_perms, is_async, requires_auth, http_method as \"http_method: _\", static_asset_config as \"static_asset_config: _\", is_static_website FROM http_trigger\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "route_path", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "route_path_key", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 8, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 10, - "name": "is_async", - "type_info": "Bool" - }, - { - "ordinal": 11, - "name": "requires_auth", - "type_info": "Bool" - }, - { - "ordinal": 12, - "name": "http_method: _", - "type_info": { - "Custom": { - "name": "http_method", - "kind": { - "Enum": [ - "get", - "post", - "put", - "delete", - "patch" - ] - } - } - } - }, - { - "ordinal": 13, - "name": "static_asset_config: _", - "type_info": "Jsonb" - }, - { - "ordinal": 14, - "name": "is_static_website", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, - false - ] - }, - "hash": "4331bb1a3559f56c1ee91916b7f15251f0b32afa2445401170d931e0fe1febb8" -} diff --git a/backend/.sqlx/query-4d3bbcc029ec0926bf97de4b5ef97dfd5eeda5977a8746be77c8aa65a7ec299e.json b/backend/.sqlx/query-4d3bbcc029ec0926bf97de4b5ef97dfd5eeda5977a8746be77c8aa65a7ec299e.json new file mode 100644 index 0000000000..4c983c95a3 --- /dev/null +++ b/backend/.sqlx/query-4d3bbcc029ec0926bf97de4b5ef97dfd5eeda5977a8746be77c8aa65a7ec299e.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS concurrency_limit_stats_completed_job", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "4d3bbcc029ec0926bf97de4b5ef97dfd5eeda5977a8746be77c8aa65a7ec299e" +} diff --git a/backend/.sqlx/query-59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023.json b/backend/.sqlx/query-59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023.json deleted file mode 100644 index d1e0d20596..0000000000 --- a/backend/.sqlx/query-59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023.json +++ /dev/null @@ -1,118 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM nats_trigger\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "nats_resource_path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "subjects", - "type_info": "VarcharArray" - }, - { - "ordinal": 3, - "name": "stream_name", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "consumer_name", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "use_jetstream", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 8, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 10, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 11, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 12, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 13, - "name": "server_id", - "type_info": "Varchar" - }, - { - "ordinal": 14, - "name": "last_server_ping", - "type_info": "Timestamptz" - }, - { - "ordinal": 15, - "name": "error", - "type_info": "Text" - }, - { - "ordinal": 16, - "name": "enabled", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - true, - true, - false, - false, - false, - false, - false, - false, - false, - false, - true, - true, - true, - false - ] - }, - "hash": "59368ac2d4e0918c7ee4275a0b1e3935e9d57be68a1811ffdee904a5f56e7023" -} diff --git a/backend/.sqlx/query-608393951c85d9e721b506d2f6a7a47667b6f9f3dc0d51987cce159433459ab0.json b/backend/.sqlx/query-608393951c85d9e721b506d2f6a7a47667b6f9f3dc0d51987cce159433459ab0.json new file mode 100644 index 0000000000..2808d96d51 --- /dev/null +++ b/backend/.sqlx/query-608393951c85d9e721b506d2f6a7a47667b6f9f3dc0d51987cce159433459ab0.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_started_at_new", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "608393951c85d9e721b506d2f6a7a47667b6f9f3dc0d51987cce159433459ab0" +} diff --git a/backend/.sqlx/query-6513c1433dbfe03f7c778963a05d964fda13a1091a8206ee174ed3a161248126.json b/backend/.sqlx/query-6513c1433dbfe03f7c778963a05d964fda13a1091a8206ee174ed3a161248126.json new file mode 100644 index 0000000000..e50d2f1154 --- /dev/null +++ b/backend/.sqlx/query-6513c1433dbfe03f7c778963a05d964fda13a1091a8206ee174ed3a161248126.json @@ -0,0 +1,25 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT id\n FROM v2_job j JOIN v2_job_queue USING (id)\n WHERE j.workspace_id = $2 AND trigger_kind = 'schedule' AND trigger = $1 AND runnable_path = $4\n AND parent_job IS NULL\n AND j.id != $3\n AND running = true", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Uuid" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Uuid", + "Text" + ] + }, + "nullable": [ + false + ] + }, + "hash": "6513c1433dbfe03f7c778963a05d964fda13a1091a8206ee174ed3a161248126" +} diff --git a/backend/.sqlx/query-6536214f31e9d600e868b01385d8c6395e2440ea27553b7ccb18d7149b106728.json b/backend/.sqlx/query-6536214f31e9d600e868b01385d8c6395e2440ea27553b7ccb18d7149b106728.json new file mode 100644 index 0000000000..fce1c4942a --- /dev/null +++ b/backend/.sqlx/query-6536214f31e9d600e868b01385d8c6395e2440ea27553b7ccb18d7149b106728.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS root_job_index_by_path_2", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "6536214f31e9d600e868b01385d8c6395e2440ea27553b7ccb18d7149b106728" +} diff --git a/backend/.sqlx/query-74754b03304a69391d61560848e89569fe5666e36ca2650dabd9b494dc30f435.json b/backend/.sqlx/query-74754b03304a69391d61560848e89569fe5666e36ca2650dabd9b494dc30f435.json new file mode 100644 index 0000000000..50372c7cc6 --- /dev/null +++ b/backend/.sqlx/query-74754b03304a69391d61560848e89569fe5666e36ca2650dabd9b494dc30f435.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_2", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "74754b03304a69391d61560848e89569fe5666e36ca2650dabd9b494dc30f435" +} diff --git a/backend/.sqlx/query-7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf.json b/backend/.sqlx/query-7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf.json deleted file mode 100644 index 6c4a2a910f..0000000000 --- a/backend/.sqlx/query-7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM postgres_trigger\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 3, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 6, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 7, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 8, - "name": "postgres_resource_path", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "error", - "type_info": "Text" - }, - { - "ordinal": 10, - "name": "server_id", - "type_info": "Varchar" - }, - { - "ordinal": 11, - "name": "last_server_ping", - "type_info": "Timestamptz" - }, - { - "ordinal": 12, - "name": "replication_slot_name", - "type_info": "Varchar" - }, - { - "ordinal": 13, - "name": "publication_name", - "type_info": "Varchar" - }, - { - "ordinal": 14, - "name": "enabled", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true, - false, - true, - true, - true, - false, - false, - false - ] - }, - "hash": "7f6649b177f4ec948e396e179ea044812f8103498080a24246063e06b0ebfccf" -} diff --git a/backend/.sqlx/query-830297547ea33969f96a5c4c2b82a540f1d147948e1b1a7523b21151ffa22305.json b/backend/.sqlx/query-830297547ea33969f96a5c4c2b82a540f1d147948e1b1a7523b21151ffa22305.json deleted file mode 100644 index 2e67b21966..0000000000 --- a/backend/.sqlx/query-830297547ea33969f96a5c4c2b82a540f1d147948e1b1a7523b21151ffa22305.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n success AS \"success!\",\n result AS \"result: Json>\",\n started_at AS \"started_at!\"FROM v2_as_completed_job WHERE workspace_id = $1 AND schedule_path = $2 AND script_path = $3 AND id != $4\n ORDER BY created_at DESC\n LIMIT $5", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "success!", - "type_info": "Bool" - }, - { - "ordinal": 1, - "name": "result: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 2, - "name": "started_at!", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Uuid", - "Int8" - ] - }, - "nullable": [ - true, - true, - true - ] - }, - "hash": "830297547ea33969f96a5c4c2b82a540f1d147948e1b1a7523b21151ffa22305" -} diff --git a/backend/.sqlx/query-833a4ecec12dfe67f28016a135ffe682b023d1868a182b7cac16ce799433c257.json b/backend/.sqlx/query-833a4ecec12dfe67f28016a135ffe682b023d1868a182b7cac16ce799433c257.json deleted file mode 100644 index 44653c2265..0000000000 --- a/backend/.sqlx/query-833a4ecec12dfe67f28016a135ffe682b023d1868a182b7cac16ce799433c257.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n UPDATE \n postgres_trigger\n SET \n last_server_ping = now(),\n error = $1\n WHERE\n workspace_id = $2\n AND path = $3\n AND server_id = $4 \n AND enabled IS TRUE\n RETURNING 1\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "?column?", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Text" - ] - }, - "nullable": [ - null - ] - }, - "hash": "833a4ecec12dfe67f28016a135ffe682b023d1868a182b7cac16ce799433c257" -} diff --git a/backend/.sqlx/query-85181656012b18cd26998128c30b1bf1f70e17486a9d315db130852d5e325200.json b/backend/.sqlx/query-85181656012b18cd26998128c30b1bf1f70e17486a9d315db130852d5e325200.json new file mode 100644 index 0000000000..98238638c1 --- /dev/null +++ b/backend/.sqlx/query-85181656012b18cd26998128c30b1bf1f70e17486a9d315db130852d5e325200.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_3", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "85181656012b18cd26998128c30b1bf1f70e17486a9d315db130852d5e325200" +} diff --git a/backend/.sqlx/query-86cc1e3c18e936a700d8842a51a6f8377ec190669e2e22f8d511871d6fbe07b8.json b/backend/.sqlx/query-86cc1e3c18e936a700d8842a51a6f8377ec190669e2e22f8d511871d6fbe07b8.json deleted file mode 100644 index 47b30f2895..0000000000 --- a/backend/.sqlx/query-86cc1e3c18e936a700d8842a51a6f8377ec190669e2e22f8d511871d6fbe07b8.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n success AS \"success!\",\n result AS \"result: Json>\",\n started_at AS \"started_at!\"\n FROM v2_as_completed_job\n WHERE workspace_id = $1 AND schedule_path = $2 AND script_path = $3 AND id != $4\n ORDER BY created_at DESC\n LIMIT $5", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "success!", - "type_info": "Bool" - }, - { - "ordinal": 1, - "name": "result: Json>", - "type_info": "Jsonb" - }, - { - "ordinal": 2, - "name": "started_at!", - "type_info": "Timestamptz" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Text", - "Uuid", - "Int8" - ] - }, - "nullable": [ - true, - true, - true - ] - }, - "hash": "86cc1e3c18e936a700d8842a51a6f8377ec190669e2e22f8d511871d6fbe07b8" -} diff --git a/backend/.sqlx/query-910b9b8afb3df5e437e43ff4adc97d0a03f6c26f0b14fc92900f7600e70a7a8b.json b/backend/.sqlx/query-910b9b8afb3df5e437e43ff4adc97d0a03f6c26f0b14fc92900f7600e70a7a8b.json new file mode 100644 index 0000000000..569a5122ba --- /dev/null +++ b/backend/.sqlx/query-910b9b8afb3df5e437e43ff4adc97d0a03f6c26f0b14fc92900f7600e70a7a8b.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT status = 'success' AS \"success!\"\n FROM v2_job j JOIN v2_job_completed USING (id)\n WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2\n AND parent_job IS NULL\n AND runnable_path = $3\n AND j.id != $4\n ORDER BY created_at DESC\n LIMIT $5", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "success!", + "type_info": "Bool" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Uuid", + "Int8" + ] + }, + "nullable": [ + null + ] + }, + "hash": "910b9b8afb3df5e437e43ff4adc97d0a03f6c26f0b14fc92900f7600e70a7a8b" +} diff --git a/backend/.sqlx/query-91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589.json b/backend/.sqlx/query-91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589.json deleted file mode 100644 index 91492c037b..0000000000 --- a/backend/.sqlx/query-91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT\n -- slack_team_id, \n -- slack_name, \n -- slack_command_script, \n -- CASE WHEN slack_email = 'missing@email.xyz' THEN NULL ELSE slack_email END AS slack_email,\n auto_invite_domain IS NOT NULL AS \"auto_invite_enabled!\",\n CASE WHEN auto_invite_operator IS TRUE THEN 'operator' ELSE 'developer' END AS \"auto_invite_as!\", \n CASE WHEN auto_add IS TRUE THEN 'add' ELSE 'invite' END AS \"auto_invite_mode!\", \n webhook, \n deploy_to, \n error_handler, \n ai_resource, \n ai_models,\n code_completion_model,\n error_handler_extra_args, \n error_handler_muted_on_cancel, \n large_file_storage, \n git_sync,\n default_app,\n default_scripts,\n workspace.name,\n mute_critical_alerts,\n color,\n operator_settings\n FROM workspace_settings\n LEFT JOIN workspace ON workspace.id = workspace_settings.workspace_id\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "auto_invite_enabled!", - "type_info": "Bool" - }, - { - "ordinal": 1, - "name": "auto_invite_as!", - "type_info": "Text" - }, - { - "ordinal": 2, - "name": "auto_invite_mode!", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "webhook", - "type_info": "Text" - }, - { - "ordinal": 4, - "name": "deploy_to", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "error_handler", - "type_info": "Varchar" - }, - { - "ordinal": 6, - "name": "ai_resource", - "type_info": "Jsonb" - }, - { - "ordinal": 7, - "name": "ai_models", - "type_info": "VarcharArray" - }, - { - "ordinal": 8, - "name": "code_completion_model", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "error_handler_extra_args", - "type_info": "Json" - }, - { - "ordinal": 10, - "name": "error_handler_muted_on_cancel", - "type_info": "Bool" - }, - { - "ordinal": 11, - "name": "large_file_storage", - "type_info": "Jsonb" - }, - { - "ordinal": 12, - "name": "git_sync", - "type_info": "Jsonb" - }, - { - "ordinal": 13, - "name": "default_app", - "type_info": "Varchar" - }, - { - "ordinal": 14, - "name": "default_scripts", - "type_info": "Jsonb" - }, - { - "ordinal": 15, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 16, - "name": "mute_critical_alerts", - "type_info": "Bool" - }, - { - "ordinal": 17, - "name": "color", - "type_info": "Varchar" - }, - { - "ordinal": 18, - "name": "operator_settings", - "type_info": "Jsonb" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - null, - null, - null, - true, - true, - true, - true, - false, - true, - true, - false, - true, - true, - true, - true, - false, - true, - true, - true - ] - }, - "hash": "91878f06c6e27d864bd50d8cd4adde4395ab6ef1181237a886fa398dcfa0b589" -} diff --git a/backend/.sqlx/query-93586f1ffc7b8dbe62b21a21acfa6854a34a99d2bf107feaafc499588f7330a0.json b/backend/.sqlx/query-93586f1ffc7b8dbe62b21a21acfa6854a34a99d2bf107feaafc499588f7330a0.json new file mode 100644 index 0000000000..b4e244e16d --- /dev/null +++ b/backend/.sqlx/query-93586f1ffc7b8dbe62b21a21acfa6854a34a99d2bf107feaafc499588f7330a0.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS scheduled_root_job", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "93586f1ffc7b8dbe62b21a21acfa6854a34a99d2bf107feaafc499588f7330a0" +} diff --git a/backend/.sqlx/query-95e420b60fba20b36b2c6675998587d8cad3b67d4dfa9de52777d4ea9490b6b7.json b/backend/.sqlx/query-95e420b60fba20b36b2c6675998587d8cad3b67d4dfa9de52777d4ea9490b6b7.json deleted file mode 100644 index 74f7f38890..0000000000 --- a/backend/.sqlx/query-95e420b60fba20b36b2c6675998587d8cad3b67d4dfa9de52777d4ea9490b6b7.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n UPDATE \n postgres_trigger \n SET\n last_server_ping = NULL \n WHERE \n workspace_id = $1 \n AND path = $2 \n AND server_id IS NULL", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "95e420b60fba20b36b2c6675998587d8cad3b67d4dfa9de52777d4ea9490b6b7" -} diff --git a/backend/.sqlx/query-9e7e6fe1dfba032e586f64531e12529d57faf5e77f6792d5bda608ff9658d7c9.json b/backend/.sqlx/query-9e7e6fe1dfba032e586f64531e12529d57faf5e77f6792d5bda608ff9658d7c9.json deleted file mode 100644 index 2ee7a1acef..0000000000 --- a/backend/.sqlx/query-9e7e6fe1dfba032e586f64531e12529d57faf5e77f6792d5bda608ff9658d7c9.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT EXISTS (SELECT 1 FROM v2_as_queue WHERE workspace_id = $1 AND schedule_path = $2 AND scheduled_for = $3)", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "exists", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Timestamptz" - ] - }, - "nullable": [ - null - ] - }, - "hash": "9e7e6fe1dfba032e586f64531e12529d57faf5e77f6792d5bda608ff9658d7c9" -} diff --git a/backend/.sqlx/query-a6c168c60bc8c42f70b18565e824efe29311aabfba6e09efa10bab6a551d658b.json b/backend/.sqlx/query-a6c168c60bc8c42f70b18565e824efe29311aabfba6e09efa10bab6a551d658b.json deleted file mode 100644 index ce9457cc6a..0000000000 --- a/backend/.sqlx/query-a6c168c60bc8c42f70b18565e824efe29311aabfba6e09efa10bab6a551d658b.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE postgres_trigger SET enabled = FALSE, error = $1, server_id = NULL, last_server_ping = NULL WHERE workspace_id = $2 AND path = $3", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Text", - "Text", - "Text" - ] - }, - "nullable": [] - }, - "hash": "a6c168c60bc8c42f70b18565e824efe29311aabfba6e09efa10bab6a551d658b" -} diff --git a/backend/.sqlx/query-a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2.json b/backend/.sqlx/query-a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2.json deleted file mode 100644 index 659dedc8cf..0000000000 --- a/backend/.sqlx/query-a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM kafka_trigger\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "path", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "kafka_resource_path", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "topics", - "type_info": "VarcharArray" - }, - { - "ordinal": 3, - "name": "group_id", - "type_info": "Varchar" - }, - { - "ordinal": 4, - "name": "script_path", - "type_info": "Varchar" - }, - { - "ordinal": 5, - "name": "is_flow", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 7, - "name": "edited_by", - "type_info": "Varchar" - }, - { - "ordinal": 8, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 9, - "name": "edited_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 10, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 11, - "name": "server_id", - "type_info": "Varchar" - }, - { - "ordinal": 12, - "name": "last_server_ping", - "type_info": "Timestamptz" - }, - { - "ordinal": 13, - "name": "error", - "type_info": "Text" - }, - { - "ordinal": 14, - "name": "enabled", - "type_info": "Bool" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - false, - true, - true, - true, - false - ] - }, - "hash": "a79b1d0884c02f92fd40b23c6181717ffa5e01250020cfb24e4bad276397dee2" -} diff --git a/backend/.sqlx/query-ca5f42cb0e368d0817461600152aabefe718829fb6eae2f681c4c8328acc94b2.json b/backend/.sqlx/query-ca5f42cb0e368d0817461600152aabefe718829fb6eae2f681c4c8328acc94b2.json deleted file mode 100644 index eb5c3a8bf0..0000000000 --- a/backend/.sqlx/query-ca5f42cb0e368d0817461600152aabefe718829fb6eae2f681c4c8328acc94b2.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT g_.workspace_id, name, summary, extra_perms, array_agg(u2g.usr) filter (where u2g.usr is not null) as members \n FROM usr u\n JOIN usr_to_group u2g ON u2g.usr = u.username AND u2g.workspace_id = u.workspace_id\n RIGHT JOIN group_ g_ ON g_.workspace_id = u.workspace_id AND g_.name = u2g.group_\n WHERE g_.workspace_id = $1 AND g_.name != 'all'\n GROUP BY g_.workspace_id, name, summary, extra_perms", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "name", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "summary", - "type_info": "Text" - }, - { - "ordinal": 3, - "name": "extra_perms", - "type_info": "Jsonb" - }, - { - "ordinal": 4, - "name": "members", - "type_info": "VarcharArray" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - true, - false, - null - ] - }, - "hash": "ca5f42cb0e368d0817461600152aabefe718829fb6eae2f681c4c8328acc94b2" -} diff --git a/backend/.sqlx/query-cb5a8545ea140ed69c7b70d8c08cb3c037309f09e84acbb7945a0466d6e9f576.json b/backend/.sqlx/query-cb5a8545ea140ed69c7b70d8c08cb3c037309f09e84acbb7945a0466d6e9f576.json new file mode 100644 index 0000000000..27330c2def --- /dev/null +++ b/backend/.sqlx/query-cb5a8545ea140ed69c7b70d8c08cb3c037309f09e84acbb7945a0466d6e9f576.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "create index concurrently if not exists ix_v2_job_root_by_path\n on v2_job (workspace_id, runnable_path, created_at DESC)\n where parent_job is null", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "cb5a8545ea140ed69c7b70d8c08cb3c037309f09e84acbb7945a0466d6e9f576" +} diff --git a/backend/.sqlx/query-d6c8f4e49cf7b6db5c979c88e02bd41c7b823186ac056a0a676da85dc5d9a027.json b/backend/.sqlx/query-d6c8f4e49cf7b6db5c979c88e02bd41c7b823186ac056a0a676da85dc5d9a027.json deleted file mode 100644 index d090c25a37..0000000000 --- a/backend/.sqlx/query-d6c8f4e49cf7b6db5c979c88e02bd41c7b823186ac056a0a676da85dc5d9a027.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT id AS \"id!\" FROM v2_as_queue WHERE schedule_path = $1 AND workspace_id = $2 AND id != $3 AND running = true", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id!", - "type_info": "Uuid" - } - ], - "parameters": { - "Left": [ - "Text", - "Text", - "Uuid" - ] - }, - "nullable": [ - true - ] - }, - "hash": "d6c8f4e49cf7b6db5c979c88e02bd41c7b823186ac056a0a676da85dc5d9a027" -} diff --git a/backend/.sqlx/query-d949e8b91fbdf4c50c1c2cbc608cf0b385bff14faab495e049f2029790f76d25.json b/backend/.sqlx/query-d949e8b91fbdf4c50c1c2cbc608cf0b385bff14faab495e049f2029790f76d25.json new file mode 100644 index 0000000000..e792f43ad4 --- /dev/null +++ b/backend/.sqlx/query-d949e8b91fbdf4c50c1c2cbc608cf0b385bff14faab495e049f2029790f76d25.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_9", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "d949e8b91fbdf4c50c1c2cbc608cf0b385bff14faab495e049f2029790f76d25" +} diff --git a/backend/.sqlx/query-e00144305b880cca3994b53c4a080e111a159a749728ce5363100cf883bdf02a.json b/backend/.sqlx/query-e00144305b880cca3994b53c4a080e111a159a749728ce5363100cf883bdf02a.json new file mode 100644 index 0000000000..d9fbfef7e2 --- /dev/null +++ b/backend/.sqlx/query-e00144305b880cca3994b53c4a080e111a159a749728ce5363100cf883bdf02a.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_8", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "e00144305b880cca3994b53c4a080e111a159a749728ce5363100cf883bdf02a" +} diff --git a/backend/.sqlx/query-e6a8ddfd74ebab55ede5989fd7d09b246b6f84e49c659bc8e2c7b66cfec6d976.json b/backend/.sqlx/query-e6a8ddfd74ebab55ede5989fd7d09b246b6f84e49c659bc8e2c7b66cfec6d976.json new file mode 100644 index 0000000000..a1b52e81fd --- /dev/null +++ b/backend/.sqlx/query-e6a8ddfd74ebab55ede5989fd7d09b246b6f84e49c659bc8e2c7b66cfec6d976.json @@ -0,0 +1,38 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT status = 'success' AS \"success!\",\n result AS \"result: Json>\",\n started_at AS \"started_at!\"FROM v2_job j JOIN v2_job_completed USING (id)\n WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2\n AND parent_job IS NULL\n AND runnable_path = $3\n AND j.id != $4\n ORDER BY created_at DESC\n LIMIT $5", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "success!", + "type_info": "Bool" + }, + { + "ordinal": 1, + "name": "result: Json>", + "type_info": "Jsonb" + }, + { + "ordinal": 2, + "name": "started_at!", + "type_info": "Timestamptz" + } + ], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Uuid", + "Int8" + ] + }, + "nullable": [ + null, + true, + true + ] + }, + "hash": "e6a8ddfd74ebab55ede5989fd7d09b246b6f84e49c659bc8e2c7b66cfec6d976" +} diff --git a/backend/.sqlx/query-e9038a6fcfd8bdf4855c5919ce634b976cbe0280e7215862aaf5ef445663793d.json b/backend/.sqlx/query-e9038a6fcfd8bdf4855c5919ce634b976cbe0280e7215862aaf5ef445663793d.json new file mode 100644 index 0000000000..13e6880b54 --- /dev/null +++ b/backend/.sqlx/query-e9038a6fcfd8bdf4855c5919ce634b976cbe0280e7215862aaf5ef445663793d.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_7", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "e9038a6fcfd8bdf4855c5919ce634b976cbe0280e7215862aaf5ef445663793d" +} diff --git a/backend/.sqlx/query-ebfd39f168722701fb63cd37aaef3741b9782d8e2d4b6ff6c104fdcac5f58323.json b/backend/.sqlx/query-ebfd39f168722701fb63cd37aaef3741b9782d8e2d4b6ff6c104fdcac5f58323.json new file mode 100644 index 0000000000..b82bb5a31c --- /dev/null +++ b/backend/.sqlx/query-ebfd39f168722701fb63cd37aaef3741b9782d8e2d4b6ff6c104fdcac5f58323.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_created_at", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "ebfd39f168722701fb63cd37aaef3741b9782d8e2d4b6ff6c104fdcac5f58323" +} diff --git a/backend/.sqlx/query-f96dd1dd944506c07ad58d178e9b6a09259fedca329d790c34e58703bf26f34c.json b/backend/.sqlx/query-f96dd1dd944506c07ad58d178e9b6a09259fedca329d790c34e58703bf26f34c.json deleted file mode 100644 index 81c15c15cf..0000000000 --- a/backend/.sqlx/query-f96dd1dd944506c07ad58d178e9b6a09259fedca329d790c34e58703bf26f34c.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT * FROM usr\n WHERE workspace_id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "workspace_id", - "type_info": "Varchar" - }, - { - "ordinal": 1, - "name": "username", - "type_info": "Varchar" - }, - { - "ordinal": 2, - "name": "email", - "type_info": "Varchar" - }, - { - "ordinal": 3, - "name": "is_admin", - "type_info": "Bool" - }, - { - "ordinal": 4, - "name": "created_at", - "type_info": "Timestamptz" - }, - { - "ordinal": 5, - "name": "operator", - "type_info": "Bool" - }, - { - "ordinal": 6, - "name": "disabled", - "type_info": "Bool" - }, - { - "ordinal": 7, - "name": "role", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Text" - ] - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - true - ] - }, - "hash": "f96dd1dd944506c07ad58d178e9b6a09259fedca329d790c34e58703bf26f34c" -} diff --git a/backend/.sqlx/query-fa94a9ee5514f6808d3813394e62c86a69b7b7378333322a57856f8e43c6cd77.json b/backend/.sqlx/query-fa94a9ee5514f6808d3813394e62c86a69b7b7378333322a57856f8e43c6cd77.json new file mode 100644 index 0000000000..6baa09af23 --- /dev/null +++ b/backend/.sqlx/query-fa94a9ee5514f6808d3813394e62c86a69b7b7378333322a57856f8e43c6cd77.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_5", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "fa94a9ee5514f6808d3813394e62c86a69b7b7378333322a57856f8e43c6cd77" +} diff --git a/backend/migrations/20250205131517_v2_skipped_is_success.down.sql b/backend/migrations/20250205131517_v2_skipped_is_success.down.sql new file mode 100644 index 0000000000..d2f607c5b8 --- /dev/null +++ b/backend/migrations/20250205131517_v2_skipped_is_success.down.sql @@ -0,0 +1 @@ +-- Add down migration script here diff --git a/backend/migrations/20250205131517_v2_skipped_is_success.up.sql b/backend/migrations/20250205131517_v2_skipped_is_success.up.sql new file mode 100644 index 0000000000..86506fe255 --- /dev/null +++ b/backend/migrations/20250205131517_v2_skipped_is_success.up.sql @@ -0,0 +1,42 @@ +-- Add up migration script here +CREATE OR REPLACE VIEW v2_as_completed_job AS +SELECT + j.id, + j.workspace_id, + j.parent_job, + j.created_by, + j.created_at, + c.duration_ms, + c.status = 'success' OR c.status = 'skipped' AS success, + j.runnable_id AS script_hash, + j.runnable_path AS script_path, + j.args, + c.result, + FALSE AS deleted, + j.raw_code, + c.status = 'canceled' AS canceled, + c.canceled_by, + c.canceled_reason, + j.kind AS job_kind, + CASE WHEN j.trigger_kind = 'schedule'::job_trigger_kind THEN j.trigger END + AS schedule_path, + j.permissioned_as, + COALESCE(c.flow_status, c.workflow_as_code_status) AS flow_status, + j.raw_flow, + j.flow_step_id IS NOT NULL AS is_flow_step, + j.script_lang AS language, + c.started_at, + c.status = 'skipped' AS is_skipped, + j.raw_lock, + j.permissioned_as_email AS email, + j.visible_to_owner, + c.memory_peak AS mem_peak, + j.tag, + j.priority, + NULL::TEXT AS logs, + c.result_columns, + j.script_entrypoint_override, + j.preprocessed +FROM v2_job_completed c + JOIN v2_job j USING (id) +; diff --git a/backend/windmill-api/src/db.rs b/backend/windmill-api/src/db.rs index a2a641b802..c4ba1d5c5d 100644 --- a/backend/windmill-api/src/db.rs +++ b/backend/windmill-api/src/db.rs @@ -504,6 +504,81 @@ async fn fix_job_completed_index(db: &DB) -> Result<(), Error> { .await?; }); + run_windmill_migration!("add_ix_v2_II", &db, { + sqlx::query!( + "create index concurrently if not exists ix_v2_job_root_by_path + on v2_job (workspace_id, runnable_path, created_at DESC) + where parent_job is null" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_3" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_5" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_6" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_7" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_8" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_9" + ) + .execute(db) + .await?; + + sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_created_at") + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_created_at_new_2" + ) + .execute(db) + .await?; + + sqlx::query!( + "DROP INDEX CONCURRENTLY IF EXISTS ix_completed_job_workspace_id_started_at_new" + ) + .execute(db) + .await?; + + sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS root_job_index_by_path_2") + .execute(db) + .await?; + + sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS scheduled_root_job") + .execute(db) + .await?; + + sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS concurrency_limit_stats_completed_job") + .execute(db) + .await?; + tracing::info!("Finished adding ix_v2_II migration"); + }); + run_windmill_migration!("fix_labeled_jobs_index", &db, { tracing::info!("Special migration to add index concurrently on job labels 2"); sqlx::query!("DROP INDEX CONCURRENTLY IF EXISTS labeled_jobs_on_jobs") diff --git a/backend/windmill-api/src/schedule.rs b/backend/windmill-api/src/schedule.rs index 109957da04..a6b6abf7dc 100644 --- a/backend/windmill-api/src/schedule.rs +++ b/backend/windmill-api/src/schedule.rs @@ -329,16 +329,29 @@ pub struct ListScheduleQuery { pub path_start: Option, } +#[derive(sqlx::FromRow, Serialize, Deserialize, Debug, Clone)] +pub struct ScheduleLight { + pub workspace_id: String, + pub path: String, + pub edited_by: String, + pub edited_at: DateTime, + pub schedule: String, + pub timezone: String, + pub enabled: bool, + pub script_path: String, + pub is_flow: bool, + pub summary: Option, +} async fn list_schedule( authed: ApiAuthed, Extension(user_db): Extension, Path(w_id): Path, Query(lsq): Query, -) -> JsonResult> { +) -> JsonResult> { let mut tx = user_db.begin(&authed).await?; let (per_page, offset) = paginate(Pagination { per_page: lsq.per_page, page: lsq.page }); let mut sqlb = SqlBuilder::select_from("schedule") - .field("*") + .field("workspace_id, path, edited_by, edited_at, schedule, timezone, enabled, script_path, is_flow, summary") .order_by("edited_at", true) .and_where("workspace_id = ?".bind(&w_id)) .offset(offset) @@ -357,7 +370,7 @@ async fn list_schedule( sqlb.and_where_like_left("path", path_start); } let sql = sqlb.sql().map_err(|e| Error::internal_err(e.to_string()))?; - let rows = sqlx::query_as::<_, Schedule>(&sql) + let rows = sqlx::query_as::<_, ScheduleLight>(&sql) .fetch_all(&mut *tx) .await?; tx.commit().await?; @@ -366,36 +379,8 @@ async fn list_schedule( #[derive(Serialize, Deserialize, Debug)] pub struct ScheduleWJobs { - pub workspace_id: String, pub path: String, - pub edited_by: String, - pub edited_at: DateTime, - pub schedule: String, - pub timezone: String, - pub enabled: bool, - pub script_path: String, - pub is_flow: bool, - pub args: Option, - pub extra_perms: serde_json::Value, - pub email: String, - pub error: Option, - pub on_failure: Option, - pub on_failure_times: Option, - pub on_failure_exact: Option, - pub on_failure_extra_args: Option, - pub on_recovery: Option, - pub on_recovery_times: Option, - pub on_recovery_extra_args: Option, - pub on_success: Option, - pub on_success_extra_args: Option, - pub ws_error_handler_muted: bool, - pub retry: Option, pub jobs: Option>, - pub summary: Option, - pub no_flow_overlap: bool, - pub tag: Option, - pub paused_until: Option>, - pub cron_version: Option, } async fn list_schedule_with_jobs( @@ -407,9 +392,27 @@ async fn list_schedule_with_jobs( let mut tx = user_db.begin(&authed).await?; let (per_page, offset) = paginate(pagination); let rows = sqlx::query_as!(ScheduleWJobs, - "SELECT schedule.*, t.jobs FROM schedule, LATERAL ( SELECT ARRAY (SELECT json_build_object('id', id, 'success', success, 'duration_ms', duration_ms) FROM v2_as_completed_job WHERE - v2_as_completed_job.schedule_path = schedule.path AND v2_as_completed_job.workspace_id = $1 AND parent_job IS NULL AND is_skipped = False ORDER BY started_at DESC LIMIT 20) AS jobs ) t - WHERE schedule.workspace_id = $1 ORDER BY schedule.edited_at desc LIMIT $2 OFFSET $3", + // Query plan: + // - use of the `ix_completed_job_workspace_id_started_at_new_2` index first, then; + // - use of the `ix_v2_job_root_by_path` index; hence the `parent_job IS NULL` clause. + // - both `workspace_id = $1` checks are required to hit both indexes. + "SELECT + schedule.path, t.jobs FROM schedule, + LATERAL(SELECT ARRAY( + SELECT json_build_object('id', id, 'success', status = 'success', 'duration_ms', duration_ms) + FROM v2_job_completed c JOIN v2_job j USING (id) + WHERE trigger_kind = 'schedule' + AND trigger = schedule.path + AND c.workspace_id = $1 + AND j.workspace_id = $1 + AND parent_job IS NULL AND runnable_path = schedule.script_path + AND status <> 'skipped' + ORDER BY created_at DESC + LIMIT 20 + ) AS jobs) t + WHERE workspace_id = $1 + ORDER BY edited_at DESC + LIMIT $2 OFFSET $3", w_id, per_page as i64, offset as i64 diff --git a/backend/windmill-queue/src/jobs.rs b/backend/windmill-queue/src/jobs.rs index f561549af8..2d2025da92 100644 --- a/backend/windmill-queue/src/jobs.rs +++ b/backend/windmill-queue/src/jobs.rs @@ -1377,12 +1377,17 @@ async fn apply_schedule_handlers<'a, 'c, T: Serialize + Send + Sync>( let exact = schedule.on_failure_exact.unwrap_or(false); if times > 1 || exact { let past_jobs = sqlx::query!( - "SELECT - success AS \"success!\", - result AS \"result: Json>\", - started_at AS \"started_at!\" - FROM v2_as_completed_job - WHERE workspace_id = $1 AND schedule_path = $2 AND script_path = $3 AND id != $4 + // Query plan: + // - use of the `ix_v2_job_root_by_path` index; + // hence the `parent_job IS NULL` clause. + // - select from `v2_job` first, then join with `v2_job_completed` to avoid a full + // table scan. + "SELECT status = 'success' AS \"success!\" + FROM v2_job j JOIN v2_job_completed USING (id) + WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2 + AND parent_job IS NULL + AND runnable_path = $3 + AND j.id != $4 ORDER BY created_at DESC LIMIT $5", &schedule.workspace_id, @@ -1448,11 +1453,19 @@ async fn apply_schedule_handlers<'a, 'c, T: Serialize + Send + Sync>( let tx = db.begin().await?; let times = schedule.on_recovery_times.unwrap_or(1).max(1); let past_jobs = sqlx::query!( - "SELECT - success AS \"success!\", + // Query plan: + // - use of the `ix_v2_job_root_by_path` index; + // hence the `parent_job IS NULL` clause. + // - select from `v2_job` first, then join with `v2_job_completed` to avoid a full + // table scan. + "SELECT status = 'success' AS \"success!\", result AS \"result: Json>\", started_at AS \"started_at!\"\ - FROM v2_as_completed_job WHERE workspace_id = $1 AND schedule_path = $2 AND script_path = $3 AND id != $4 + FROM v2_job j JOIN v2_job_completed USING (id) + WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2 + AND parent_job IS NULL + AND runnable_path = $3 + AND j.id != $4 ORDER BY created_at DESC LIMIT $5", &schedule.workspace_id, diff --git a/backend/windmill-queue/src/schedule.rs b/backend/windmill-queue/src/schedule.rs index fd4bcab4b4..f36722dbe9 100644 --- a/backend/windmill-queue/src/schedule.rs +++ b/backend/windmill-queue/src/schedule.rs @@ -9,7 +9,7 @@ use crate::push; use crate::PushIsolationLevel; use anyhow::Context; -use sqlx::{query_scalar, PgExecutor, Postgres, Transaction}; +use sqlx::{PgExecutor, Postgres, Transaction}; use std::collections::HashMap; use std::str::FromStr; use windmill_common::db::Authed; @@ -70,11 +70,21 @@ pub async fn push_scheduled_job<'c>( // Scheduled events must be stored in the database in UTC let next = next.with_timezone(&chrono::Utc); - let already_exists: bool = query_scalar!( - "SELECT EXISTS (SELECT 1 FROM v2_as_queue WHERE workspace_id = $1 AND schedule_path = $2 AND scheduled_for = $3)", + let already_exists: bool = sqlx::query_scalar!( + // Query plan: + // - use of the `ix_v2_job_root_by_path` index; hence the `parent_job IS NULL` clause. + // - select from `v2_job` first, then join with `v2_job_queue` to avoid a full table scan + // on `scheduled_for = $3`. + "SELECT EXISTS ( + SELECT 1 FROM v2_job j JOIN v2_job_queue USING (id) + WHERE j.workspace_id = $1 AND trigger_kind = 'schedule' AND trigger = $2 AND runnable_path = $4 + AND parent_job IS NULL + AND scheduled_for = $3 + )", &schedule.workspace_id, &schedule.path, - next + next, + &schedule.script_path ) .fetch_one(&mut *tx) .await? diff --git a/backend/windmill-worker/src/common.rs b/backend/windmill-worker/src/common.rs index a64a32c869..995638ecb2 100644 --- a/backend/windmill-worker/src/common.rs +++ b/backend/windmill-worker/src/common.rs @@ -333,7 +333,8 @@ pub fn unsafe_raw(json: String) -> Box { fn check_result_too_big(size: usize) -> error::Result<()> { if *CLOUD_HOSTED && size > MAX_RESULT_SIZE { return Err(error::Error::ExecutionErr("Result is too large for the cloud app (limit 2MB). - If using this script as part of the flow, use the shared folder to pass heavy data between steps.".to_owned())); +We highly recommend using object to store and pass heavy data (https://www.windmill.dev/docs/core_concepts/object_storage_in_windmill#read-a-file-from-s3-within-a-script) +Alternatively, if using this script as part of a flow, activate shared folder and use the shared folder to pass heavy data between steps.".to_owned())); }; Ok(()) } diff --git a/backend/windmill-worker/src/worker_flow.rs b/backend/windmill-worker/src/worker_flow.rs index 42dd66c217..5e4224681f 100644 --- a/backend/windmill-worker/src/worker_flow.rs +++ b/backend/windmill-worker/src/worker_flow.rs @@ -1711,11 +1711,24 @@ async fn push_next_flow_job( .await?; if no_flow_overlap { let overlapping = sqlx::query_scalar!( - "SELECT id AS \"id!\" FROM v2_as_queue WHERE schedule_path = $1 AND workspace_id = $2 AND id != $3 AND running = true", + // Query plan: + // - use of the `ix_v2_job_root_by_path` index; hence the `parent_job IS NULL` + // clause. + // - select from `v2_job` first, then join with `v2_job_queue` to avoid a full + // table scan on `running = true`. + "SELECT id + FROM v2_job j JOIN v2_job_queue USING (id) + WHERE j.workspace_id = $2 AND trigger_kind = 'schedule' AND trigger = $1 AND runnable_path = $4 + AND parent_job IS NULL + AND j.id != $3 + AND running = true", flow_job.schedule_path.as_ref().unwrap(), flow_job.workspace_id.as_str(), - flow_job.id - ).fetch_all(db).await?; + flow_job.id, + flow_job.script_path.as_ref().unwrap() + ) + .fetch_all(db) + .await?; if overlapping.len() > 0 { let overlapping_str = overlapping .iter() diff --git a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte index 093fb41032..4e9cebe228 100644 --- a/frontend/src/lib/components/apps/editor/SubGridEditor.svelte +++ b/frontend/src/lib/components/apps/editor/SubGridEditor.svelte @@ -331,6 +331,6 @@ {:else if $app.lazyInitRequire == undefined} {#each $app?.subgrids?.[subGridId] ?? [] as item} - + {/each} {/if} diff --git a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte index cad5a7ee4f..cce869583c 100644 --- a/frontend/src/routes/(root)/(logged)/schedules/+page.svelte +++ b/frontend/src/routes/(root)/(logged)/schedules/+page.svelte @@ -232,12 +232,9 @@ } onMount(() => { - console.log(`on mount: `, $userStore?.operator, $workspaceStore, $userWorkspaces) loadQueryFilters() }) - $: $userWorkspaces && $userStore && $workspaceStore && console.log(`user workspaces: `, $userWorkspaces) - $: updateQueryFilters(selectedFilterKind, filterUserFolders, filterEnabledDisabled) @@ -250,265 +247,267 @@ f={(x) => (x.summary ?? '') + ' ' + x.path + ' (' + x.script_path + ')'} /> -{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find(_ => _.id === $workspaceStore)?.operator_settings?.schedules} - +{#if $userStore?.operator && $workspaceStore && !$userWorkspaces.find((_) => _.id === $workspaceStore)?.operator_settings?.schedules} + {:else} - - - - -
-
- -
-
Filter by path of
- - - - -
- + + + + +
+
+ +
+
Filter by path of
+ + + + +
+ -
- - - - - - {#if $userStore?.is_super_admin && $userStore.username.includes('@')} - - {:else if $userStore?.is_admin || $userStore?.is_super_admin} - - {/if} +
+ + + + + + {#if $userStore?.is_super_admin && $userStore.username.includes('@')} + + {:else if $userStore?.is_admin || $userStore?.is_super_admin} + + {/if} +
-
- {#if loading} - {#each new Array(6) as _} - - {/each} - {:else if !schedules?.length} -
No schedules
- {:else if items?.length} -
- {#each items.slice(0, nbDisplayed) as { path, error, summary, edited_by, edited_at, schedule, timezone, enabled, script_path, is_flow, extra_perms, canWrite, args, marked, jobs, paused_until } (path)} - {@const href = `${is_flow ? '/flows/get' : '/scripts/get'}/${script_path}`} - {@const avg_s = jobs - ? jobs.reduce((acc, x) => acc + x.duration_ms, 0) / jobs.length - : undefined} + {#if loading} + {#each new Array(6) as _} + + {/each} + {:else if !schedules?.length} +
No schedules
+ {:else if items?.length} +
+ {#each items.slice(0, nbDisplayed) as { path, error, summary, edited_by, edited_at, schedule, timezone, enabled, script_path, is_flow, extra_perms, canWrite, args, marked, jobs, paused_until } (path)} + {@const href = `${is_flow ? '/flows/get' : '/scripts/get'}/${script_path}`} + {@const avg_s = jobs + ? jobs.reduce((acc, x) => acc + x.duration_ms, 0) / jobs.length + : undefined} -
-
- + > +
+ - scheduleEditor?.openEdit(path, is_flow)} - class="min-w-0 grow hover:underline decoration-gray-400" - > -
- {#if marked} - - {@html marked} - - {:else} - {summary || script_path} - {/if} -
-
- schedule: {path} -
-
- - {#if paused_until && new Date(paused_until) > new Date()} -
- Paused until {new Date(paused_until).toLocaleString()} -
- {/if} - - - - - -
- {#if error} - - - - - -
- The schedule disabled itself because there was an error scheduling the next - job: {error} -
-
- {/if} -
- - { - if (canWrite) { - setScheduleEnabled(path, e.detail) - } else { - sendUserToast('not enough permission', true) - } - }} - /> -
- - - { - goto(href) - } - }, - { - displayName: 'Delete', - type: 'delete', - icon: Trash, - disabled: !canWrite, - action: async () => { - await ScheduleService.deleteSchedule({ - workspace: $workspaceStore ?? '', - path - }) - loadSchedules() - } - }, - { - displayName: canWrite ? 'Edit' : 'View', - icon: canWrite ? Pen : Eye, - action: () => { - scheduleEditor?.openEdit(path, is_flow) - } - }, - { - displayName: 'View runs', - icon: List, - href: - base + - '/runs/?schedule_path=' + - path + - '&show_schedules=true&show_future_jobs=true' - }, - { - displayName: 'Audit logs', - icon: Eye, - href: `${base}/audit_logs?resource=${path}` - }, - { - displayName: 'Run now', - icon: Play, - action: () => { - runScheduleNow(script_path, args, is_flow) - } - }, - { - displayName: canWrite ? 'Share' : 'See Permissions', - icon: Share, - action: () => { - shareModal.openDrawer(path, 'schedule') - } - } - ]} - /> -
-
-
- {#if loadingSchedulesWithJobStats} -
- - Job stats loading... +
+ {#if marked} + + {@html marked} + + {:else} + {summary || script_path} + {/if} +
+
+ schedule: {path} +
+ + + {#if paused_until && new Date(paused_until) > new Date()} +
+ Paused until {new Date(paused_until).toLocaleString()} +
+ {/if} + + - {:else} -
- {#if avg_s} -
Avg: {(avg_s / 1000).toFixed(2)}s
+ + + +
+ {#if error} + + + + + +
+ The schedule disabled itself because there was an error scheduling the next + job: {error} +
+
{/if} - {#each jobs ?? [] as job} - {@const h = (avg_s ? job.duration_ms / avg_s : 1) * 7 + 3} - - -
-
- -
- -
- {/each} -
- {/if} -
edited by {edited_by}
the {displayDate(edited_at)}
+ + + {/each} +
+ {/if} +
edited by {edited_by}
the {displayDate(edited_at)}
-
- {/each} -
- {:else} - + > +
+ {/each} +
+ {:else} + + {/if} +
+ {#if items && items?.length > 15 && nbDisplayed < items.length} + {nbDisplayed} items out of {items.length} + {/if} -
- {#if items && items?.length > 15 && nbDisplayed < items.length} - {nbDisplayed} items out of {items.length} - - {/if} - + {/if}