diff --git a/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.down.sql b/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.down.sql new file mode 100644 index 0000000000..d2f607c5b8 --- /dev/null +++ b/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.down.sql @@ -0,0 +1 @@ +-- Add down migration script here diff --git a/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.up.sql b/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.up.sql new file mode 100644 index 0000000000..2c7f5039fd --- /dev/null +++ b/backend/migrations/20230227100232_update_included_scripts_with_deno_changes.up.sql @@ -0,0 +1,1182 @@ + +with _insert as +( +INSERT INTO + app_version(app_id, created_by, created_at, value) +VALUES + ( + ( + SELECT + id + FROM + app + WHERE + workspace_id = 'admins' + AND path = 'g/all/setup_app' + ), + 'admin@windmill.dev', + '2023-01-01 00:00:00.000000 +00:00', + '{ + "grid": [ + { + "3": { + "h": 1, + "w": 3, + "x": 0, + "y": 0, + "id": "a", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 2, + "w": 12, + "x": 0, + "y": 0, + "id": "a", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "a", + "data": { + "id": "a", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Title", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "Setup your Windmill instance", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 0, + "y": 6, + "id": "c", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 1, + "y": 6, + "id": "c", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "c", + "data": { + "id": "c", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Label", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "Old Email", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "left" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 2, + "y": 6, + "id": "d", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 7, + "y": 6, + "id": "d", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "d", + "data": { + "id": "d", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Label", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "New Email", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "left" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 2, + "y": 8, + "id": "e", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 7, + "y": 8, + "id": "e", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "e", + "data": { + "id": "e", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Label", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "New Password", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "left" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 2, + "y": 7, + "id": "g", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 7, + "y": 7, + "id": "g", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "g", + "data": { + "id": "g", + "card": false, + "type": "textinputcomponent", + "softWrap": true, + "configuration": { + "placeholder": { + "type": "static", + "value": "Type...", + "fieldType": "text", + "onlyStatic": true + }, + "defaultValue": { + "type": "static", + "fieldType": "text" + } + }, + "verticalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 2, + "y": 9, + "id": "i", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 7, + "y": 9, + "id": "i", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "i", + "data": { + "id": "i", + "card": false, + "type": "passwordinputcomponent", + "softWrap": true, + "configuration": { + "placeholder": { + "type": "static", + "value": "Password", + "fieldType": "text", + "onlyStatic": true + } + }, + "verticalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 3, + "x": 0, + "y": 1, + "id": "l", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 12, + "x": 0, + "y": 2, + "id": "l", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "l", + "data": { + "id": "l", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Subtitle", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "Setup a secure account", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 3, + "w": 3, + "x": 0, + "y": 2, + "id": "m", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 3, + "w": 10, + "x": 1, + "y": 3, + "id": "m", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "m", + "data": { + "id": "m", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Body", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "The below button will replace your account with a new one.\nYou''ll have to log in again.", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 2, + "x": 0, + "y": 17, + "id": "n", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 2, + "y": 17, + "id": "n", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "n", + "data": { + "id": "n", + "card": false, + "type": "checkboxcomponent", + "softWrap": true, + "configuration": { + "label": { + "type": "static", + "value": "Enable Hub Sync", + "fieldType": "text" + }, + "defaultValue": { + "type": "static", + "value": true, + "fieldType": "boolean" + } + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 3, + "w": 3, + "x": 0, + "y": 14, + "id": "o", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 3, + "w": 8, + "x": 2, + "y": 14, + "id": "o", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "o", + "data": { + "id": "o", + "card": false, + "type": "textcomponent", + "softWrap": true, + "configuration": { + "style": { + "type": "static", + "value": "Body", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "We recommend enabling hub sync below. This will create a schedule in the admin workspace on behalf of the new user once you press the button. This schedule will automatically syncronize resource types from the hub to your local instance.", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 1, + "x": 2, + "y": 17, + "id": "p", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 4, + "x": 6, + "y": 17, + "id": "p", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "p", + "data": { + "id": "p", + "card": false, + "type": "textinputcomponent", + "softWrap": true, + "configuration": { + "placeholder": { + "type": "static", + "value": "Type...", + "fieldType": "text", + "onlyStatic": true + }, + "defaultValue": { + "type": "static", + "value": "0 0 0 * * *", + "fieldType": "text" + } + }, + "verticalAlignment": "center" + } + }, + { + "3": { + "h": 3, + "w": 3, + "x": 0, + "y": 19, + "id": "u", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 2, + "w": 8, + "x": 2, + "y": 19, + "id": "u", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "u", + "data": { + "id": "u", + "card": false, + "type": "buttoncomponent", + "softWrap": true, + "configuration": { + "size": { + "type": "static", + "value": "lg", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "buttonSizeOptions" + }, + "color": { + "type": "static", + "value": "red", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "buttonColorOptions" + }, + "label": { + "type": "static", + "value": "Change account and set hub sync - re-login necessary", + "fieldType": "text" + }, + "disabled": { + "expr": "g.result == \"\" || i.result == \"\"", + "type": "eval", + "fieldType": "boolean" + }, + "fillContainer": { + "type": "static", + "value": true, + "fieldType": "boolean", + "onlyStatic": true + }, + "goto": { + "type": "static", + "value": "/user/logout", + "fieldType": "text", + "onlyStatic": true + } + }, + "componentInput": { + "type": "runnable", + "fields": { + "oldEmail": { + "type": "connected", + "value": null, + "fieldType": "string", + "connection": { + "componentId": "ctx", + "path": "email" + } + }, + "newEmail": { + "type": "connected", + "value": null, + "format": "", + "fieldType": "string", + "connection": { + "path": "result", + "componentId": "g" + } + }, + "newPassword": { + "type": "connected", + "value": null, + "format": "", + "fieldType": "string", + "connection": { + "path": "result", + "componentId": "i" + } + }, + "enable_hub_sync": { + "type": "connected", + "value": null, + "format": "", + "fieldType": "boolean", + "connection": { + "path": "result", + "componentId": "n" + } + }, + "cron_str": { + "type": "connected", + "value": null, + "fieldType": "string", + "connection": { + "path": "result", + "componentId": "p" + } + } + }, + "runnable": { + "name": "Change Account", + "type": "runnableByName", + "inlineScript": { + "path": "/inline-script/Inline Script 0", + "schema": { + "type": "object", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "required": [ + "oldEmail", + "newEmail", + "newPassword", + "enable_hub_sync", + "cron_str" + ], + "properties": { + "oldEmail": { + "description": "", + "type": "string", + "default": null + }, + "newEmail": { + "type": "string", + "format": "", + "default": null, + "description": "" + }, + "newPassword": { + "type": "string", + "format": "", + "default": null, + "description": "" + }, + "enable_hub_sync": { + "type": "boolean", + "format": "", + "default": null, + "description": "" + }, + "cron_str": { + "type": "string", + "default": null, + "description": "" + } + } + }, + "content": "import * as wmill from \"https://deno.land/x/windmill@v1.69.3/mod.ts\";\n\nexport async function main(\n oldEmail: string,\n newEmail: string,\n newPassword: string,\n enable_hub_sync: boolean,\n cron_str: string,\n) {\n await wmill.UserService.createUserGlobally({\n requestBody: {\n email: newEmail,\n password: newPassword,\n super_admin: true,\n },\n });\n\n const new_token = await wmill.UserService.login({\n requestBody: {\n email: newEmail,\n password: newPassword,\n },\n });\n\n wmill.setClient(new_token, Deno.env.get(\"BASE_INTERNAL_URL\")!);\n await wmill.JobService.runScriptByPath({\n workspace: \"admins\",\n path: \"u/admin/hub_sync\",\n requestBody: {},\n });\n \n if (enable_hub_sync) {\n try {\n await wmill.ScheduleService.createSchedule({\n workspace: \"admins\",\n requestBody: {\n path: \"g/all/hub_sync\",\n schedule: cron_str,\n script_path: \"u/admin/hub_sync\",\n is_flow: false,\n args: {},\n enabled: true,\n offset: 0,\n },\n });\n } catch {\n console.log(\"Schedule already exists\");\n }\n }\n\n await wmill.UserService.globalUserDelete({ email: oldEmail });\n}\n", + "language": "deno" + } + }, + "fieldType": "any" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "h": 1, + "w": 3, + "x": 0, + "y": 13, + "id": "v", + "max": { + "h": 100, + "w": 3 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "12": { + "h": 1, + "w": 12, + "x": 0, + "y": 13, + "id": "v", + "max": { + "h": 100, + "w": 12 + }, + "min": { + "h": 1, + "w": 1 + }, + "fixed": true, + "draggable": true, + "resizable": true, + "customDragger": false, + "customResizer": false + }, + "id": "v", + "data": { + "id": "v", + "card": false, + "type": "textcomponent", + "softWrap": false, + "configuration": { + "style": { + "type": "static", + "value": "Subtitle", + "fieldType": "select", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + }, + "extraStyle": { + "type": "static", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"", + "fieldType": "text" + } + }, + "componentInput": { + "eval": "Setup Hub Sync", + "type": "template", + "value": "Hello ${ctx.username}", + "fieldType": "template" + }, + "verticalAlignment": "center", + "horizontalAlignment": "center" + } + }, + { + "3": { + "fixed": false, + "resizable": true, + "draggable": true, + "customDragger": false, + "customResizer": false, + "x": 0, + "y": 5, + "min": { + "w": 1, + "h": 1 + }, + "max": { + "w": 3, + "h": 100 + }, + "w": 1, + "h": 1 + }, + "12": { + "fixed": false, + "resizable": true, + "draggable": true, + "customDragger": false, + "customResizer": false, + "x": 1, + "y": 7, + "min": { + "w": 1, + "h": 1 + }, + "max": { + "w": 12, + "h": 100 + }, + "w": 4, + "h": 1, + "id": "w" + }, + "data": { + "softWrap": false, + "horizontalAlignment": "left", + "verticalAlignment": "center", + "id": "w", + "type": "textcomponent", + "componentInput": { + "type": "template", + "fieldType": "template", + "value": "Hello ${ctx.username}", + "eval": "${ctx.username}" + }, + "configuration": { + "style": { + "fieldType": "select", + "type": "static", + "onlyStatic": true, + "optionValuesKey": "textStyleOptions", + "value": "Body" + }, + "extraStyle": { + "type": "static", + "fieldType": "text", + "value": "", + "tooltip": "CSS rules like \"color: blue;\"" + }, + "copyButton": { + "type": "static", + "value": false, + "fieldType": "boolean", + "onlyStatic": true + } + }, + "card": false + }, + "id": "w" + } + ], + "fullscreen": false, + "hiddenInlineScripts": [], + "unusedInlineScripts": [] +}') RETURNING id) +UPDATE app SET versions = ARRAY((select id from _insert)), policy = '{ "execution_mode": "viewer", "triggerables": {} }' + WHERE workspace_id = 'admins' AND path = 'g/all/setup_app'; + +UPDATE script SET content = 'import wmill from "https://deno.land/x/wmill@v1.69.3/main.ts"; +export async function main() { + await run( + "workspace", "add", "__automation", "admins", Deno.env.get("BASE_INTERNAL_URL") + "/", "--token", Deno.env.get("WM_TOKEN")); + + await run("hub", "pull"); +} + +async function run(...cmd: string[]) { + console.log("Running \"" + cmd.join('' '') + "\""); + await wmill.parse(cmd); +}', summary = 'Synchronize Hub Resource types with admins workspace', +description = 'Basic administrative script to sync latest resource types from hub to share to every workspace. Recommended to run at least once. On a schedule by default.' +WHERE hash = -28028598712388162 AND workspace_id = 'admins'; \ No newline at end of file diff --git a/backend/windmill-queue/src/jobs.rs b/backend/windmill-queue/src/jobs.rs index e17e6e3b52..2d5223489f 100644 --- a/backend/windmill-queue/src/jobs.rs +++ b/backend/windmill-queue/src/jobs.rs @@ -351,7 +351,10 @@ pub async fn push<'c>( .unwrap_or(false); if !is_super_admin { - if usage > MAX_FREE_EXECS { + if usage > MAX_FREE_EXECS + && !matches!(job_payload, JobPayload::Dependencies { .. }) + && !matches!(job_payload, JobPayload::FlowDependencies { .. }) + { return Err(error::Error::BadRequest(format!( "User {email} has exceeded the free usage limit of {MAX_FREE_EXECS} that applies outside of premium workspaces." ))); @@ -466,10 +469,10 @@ pub async fn push<'c>( } JobPayload::Flow(flow) => { let value_json = sqlx::query_scalar!( - "SELECT value FROM flow WHERE path = $1 AND workspace_id = $2", - flow, - workspace_id - ) + "SELECT value FROM flow WHERE path = $1 AND workspace_id = $2", + flow, + workspace_id + ) .fetch_optional(&mut tx) .await? .ok_or_else(|| Error::InternalErr(format!("not found flow at path {:?}", flow)))?; diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index 4fbe1e5c92..c3e5f939f1 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -383,7 +383,7 @@ lazy_static::lazy_static! { .unwrap(); static ref WORKER_UPTIME_OPTS: prometheus::Opts = prometheus::opts!( "worker_uptime", - "Total number of milliseconds since the worker has started" + "Total number of seconds since the worker has started" ); static ref TIMEOUT: u16 = std::env::var("TIMEOUT") @@ -445,15 +445,11 @@ pub async fn run_worker( insert_initial_ping(worker_instance, &worker_name, ip, db).await; - let uptime_metric = prometheus::register_int_counter!(WORKER_UPTIME_OPTS + let uptime_metric = prometheus::register_counter!(WORKER_UPTIME_OPTS .clone() .const_label("name", &worker_name)) .unwrap(); - uptime_metric.inc_by( - ((Instant::now() - start_time).as_millis() - uptime_metric.get() as u128) - .try_into() - .unwrap(), - ); + let worker_execution_duration = prometheus::register_histogram_vec!( prometheus::HistogramOpts::new( @@ -465,6 +461,14 @@ pub async fn run_worker( ) .expect("register prometheus metric"); + let worker_execution_duration_counter = prometheus::register_counter!(prometheus::opts!( + "worker_execution_duration_counter", + "Total number of seconds spent executing jobs" + ) + .const_label("name", &worker_name)) + .expect("register prometheus metric"); + + let worker_sleep_duration = prometheus::register_histogram!(prometheus::HistogramOpts::new( "worker_sleep_duration", "Duration sleeping waiting for job", @@ -472,6 +476,15 @@ pub async fn run_worker( .const_label("name", &worker_name),) .expect("register prometheus metric"); + + let worker_sleep_duration_counter = prometheus::register_counter!(prometheus::opts!( + "worker_execution_sleep_counter", + "Total number of seconds spent sleeping between pulling jobs from the queue" + ) + .const_label("name", &worker_name)) + .expect("register prometheus metric"); + + let worker_pull_duration = prometheus::register_histogram!(prometheus::HistogramOpts::new( "worker_pull_duration", "Duration pulling next job", @@ -479,6 +492,13 @@ pub async fn run_worker( .const_label("name", &worker_name),) .expect("register prometheus metric"); + let worker_pull_duration_counter = prometheus::register_counter!(prometheus::opts!( + "worker_pull_sleep_counter", + "Total number of seconds spent pulling jobs (if growing large the db is undersized)" + ) + .const_label("name", &worker_name)) + .expect("register prometheus metric"); + let worker_execution_failed = prometheus::register_int_counter_vec!( prometheus::Opts::new("worker_execution_failed", "Number of failed jobs",) .const_label("name", &worker_name), @@ -526,11 +546,12 @@ pub async fn run_worker( worker_busy.set(0); uptime_metric.inc_by( - ((Instant::now() - start_time).as_millis() - uptime_metric.get() as u128) + (((Instant::now() - start_time).as_millis() as f64)/1000.0 - uptime_metric.get()) .try_into() .unwrap(), ); + let do_break = async { if last_ping.elapsed().as_secs() > NUM_SECS_ENV_CHECK { sqlx::query!( @@ -574,7 +595,8 @@ pub async fn run_worker( (job, timer) = { let timer = worker_pull_duration.start_timer(); pull(&db, WHITELIST_WORKSPACES.clone(), BLACKLIST_WORKSPACES.clone()).map(|x| (x, timer)) } => { - drop(timer); + let duration_pull_s = timer.stop_and_record(); + worker_pull_duration_counter.inc_by(duration_pull_s); (false, job) }, } @@ -680,6 +702,8 @@ pub async fn run_worker( .await; }; + let duration = _timer.stop_and_record(); + worker_execution_duration_counter.inc_by(duration); if !*KEEP_JOB_DIR && !(is_flow && same_worker) { let _ = tokio::fs::remove_dir_all(job_dir).await; @@ -689,9 +713,9 @@ pub async fn run_worker( let _timer = worker_sleep_duration .start_timer(); - tokio::time::sleep(Duration::from_millis(*SLEEP_QUEUE)).await; - + let duration = _timer.stop_and_record(); + worker_sleep_duration_counter.inc_by(duration); } Err(err) => { tracing::error!(worker = %worker_name, "run_worker: pulling jobs: {}", err); diff --git a/cli/login.ts b/cli/login.ts index 8332f909d4..530df9a1f7 100644 --- a/cli/login.ts +++ b/cli/login.ts @@ -54,7 +54,7 @@ export async function browserLogin( await open(url) console.log("Opened browser for you"); } catch { - console.error(`Failed to open browser, please navgiate to ${url}`) + console.error(`Failed to open browser, please navigate to ${url}`) } const firstConnection = await server.accept(); const httpFirstConnection = Deno.serveHttp(firstConnection); diff --git a/frontend/vite.config.js.timestamp-1677450565189.mjs b/frontend/vite.config.js.timestamp-1677450565189.mjs deleted file mode 100644 index e69de29bb2..0000000000