fix: make GetWorkspacesEligibleForTransition return even less false positives (#15594)

Relates to https://github.com/coder/coder/issues/15082

Further to https://github.com/coder/coder/pull/15429, this reduces the
amount of false-positives returned by the 'is eligible for autostart'
part of the query. We achieve this by calculating the 'next start at'
time of the workspace, storing it in the database, and using it in our
`GetWorkspacesEligibleForTransition` query.

The prior implementation of the 'is eligible for autostart' query would
return _all_ workspaces that at some point in the future _might_ be
eligible for autostart. This now ensures we only return workspaces that
_should_ be eligible for autostart.

We also now pass `currentTick` instead of `t` to the
`GetWorkspacesEligibleForTransition` query as otherwise we'll have one
round of workspaces that are skipped by `isEligibleForTransition` due to
`currentTick` being a truncated version of `t`.
This commit is contained in:
Danielle Maywood
2024-12-02 21:02:36 +00:00
committed by GitHub
parent 2b57dcc68c
commit e21a301682
35 changed files with 1012 additions and 75 deletions
+28 -1
View File
@@ -380,6 +380,25 @@ BEGIN
END;
$$;
CREATE FUNCTION nullify_next_start_at_on_workspace_autostart_modification() RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
BEGIN
-- A workspace's next_start_at might be invalidated by the following:
-- * The autostart schedule has changed independent to next_start_at
-- * The workspace has been marked as dormant
IF (NEW.autostart_schedule <> OLD.autostart_schedule AND NEW.next_start_at = OLD.next_start_at)
OR (NEW.dormant_at IS NOT NULL AND NEW.next_start_at IS NOT NULL)
THEN
UPDATE workspaces
SET next_start_at = NULL
WHERE id = NEW.id;
END IF;
RETURN NEW;
END;
$$;
CREATE FUNCTION provisioner_tagset_contains(provisioner_tags tagset, job_tags tagset) RETURNS boolean
LANGUAGE plpgsql
AS $$
@@ -1731,7 +1750,8 @@ CREATE TABLE workspaces (
dormant_at timestamp with time zone,
deleting_at timestamp with time zone,
automatic_updates automatic_updates DEFAULT 'never'::automatic_updates NOT NULL,
favorite boolean DEFAULT false NOT NULL
favorite boolean DEFAULT false NOT NULL,
next_start_at timestamp with time zone
);
COMMENT ON COLUMN workspaces.favorite IS 'Favorite is true if the workspace owner has favorited the workspace.';
@@ -1752,6 +1772,7 @@ CREATE VIEW workspaces_expanded AS
workspaces.deleting_at,
workspaces.automatic_updates,
workspaces.favorite,
workspaces.next_start_at,
visible_users.avatar_url AS owner_avatar_url,
visible_users.username AS owner_username,
organizations.name AS organization_name,
@@ -2110,10 +2131,14 @@ CREATE INDEX workspace_app_stats_workspace_id_idx ON workspace_app_stats USING b
CREATE INDEX workspace_modules_created_at_idx ON workspace_modules USING btree (created_at);
CREATE INDEX workspace_next_start_at_idx ON workspaces USING btree (next_start_at) WHERE (deleted = false);
CREATE UNIQUE INDEX workspace_proxies_lower_name_idx ON workspace_proxies USING btree (lower(name)) WHERE (deleted = false);
CREATE INDEX workspace_resources_job_id_idx ON workspace_resources USING btree (job_id);
CREATE INDEX workspace_template_id_idx ON workspaces USING btree (template_id) WHERE (deleted = false);
CREATE UNIQUE INDEX workspaces_owner_id_lower_idx ON workspaces USING btree (owner_id, lower((name)::text)) WHERE (deleted = false);
CREATE OR REPLACE VIEW provisioner_job_stats AS
@@ -2192,6 +2217,8 @@ CREATE TRIGGER trigger_delete_oauth2_provider_app_token AFTER DELETE ON oauth2_p
CREATE TRIGGER trigger_insert_apikeys BEFORE INSERT ON api_keys FOR EACH ROW EXECUTE FUNCTION insert_apikey_fail_if_user_deleted();
CREATE TRIGGER trigger_nullify_next_start_at_on_workspace_autostart_modificati AFTER UPDATE ON workspaces FOR EACH ROW EXECUTE FUNCTION nullify_next_start_at_on_workspace_autostart_modification();
CREATE TRIGGER trigger_update_users AFTER INSERT OR UPDATE ON users FOR EACH ROW WHEN ((new.deleted = true)) EXECUTE FUNCTION delete_deleted_user_resources();
CREATE TRIGGER trigger_upsert_user_links BEFORE INSERT OR UPDATE ON user_links FOR EACH ROW EXECUTE FUNCTION insert_user_links_fail_if_user_deleted();