Filter query: has-agent connecting, connected, disconnected, timeout (#5145)

* WIP

* has-agent:connecting, connected

* Fix

* Fix

* has-agent:disconnected, timeout

* Fix: typo

* Fix

* TODOs

* databasefake

* Fix: typo

* More TODOs

* databasefake

* Timeout tests

* Address PR comments

* Implement FIXMEs

* Renamings

* Address PR comments

* Fix: readability

* Fix: refactor CASE logic

* CASE logic

* Fix

* Use CTE

* Polishing

* Comment

* WIP

* IS NOT NULL

* Without CTE

* One more optimization

* 2nd optimization
This commit is contained in:
Marcin Tojek
2022-11-24 15:33:13 +01:00
committed by GitHub
parent 511bb469c4
commit 25da224513
7 changed files with 336 additions and 27 deletions
+58 -16
View File
@@ -6272,6 +6272,7 @@ FROM
LEFT JOIN LATERAL (
SELECT
workspace_builds.transition,
provisioner_jobs.id AS provisioner_job_id,
provisioner_jobs.started_at,
provisioner_jobs.updated_at,
provisioner_jobs.canceled_at,
@@ -6373,7 +6374,7 @@ WHERE
-- Use the organization filter to restrict to 1 org if needed.
AND CASE
WHEN $5 :: text != '' THEN
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($5) AND deleted = false)
template_id = ANY(SELECT id FROM templates WHERE lower(name) = lower($5) AND deleted = false)
ELSE true
END
-- Filter by template_ids
@@ -6388,29 +6389,68 @@ WHERE
name ILIKE '%' || $7 || '%'
ELSE true
END
-- Filter by agent status
-- has-agent: is only applicable for workspaces in "start" transition. Stopped and deleted workspaces don't have agents.
AND CASE
WHEN $8 :: text != '' THEN
(
SELECT COUNT(*)
FROM
workspace_resources
JOIN
workspace_agents
ON
workspace_agents.resource_id = workspace_resources.id
WHERE
workspace_resources.job_id = latest_build.provisioner_job_id AND
latest_build.transition = 'start'::workspace_transition AND
$8 = (
CASE
WHEN workspace_agents.first_connected_at IS NULL THEN
CASE
WHEN workspace_agents.connection_timeout_seconds > 0 AND NOW() - workspace_agents.created_at > workspace_agents.connection_timeout_seconds * INTERVAL '1 second' THEN
'timeout'
ELSE
'connecting'
END
WHEN workspace_agents.disconnected_at > workspace_agents.last_connected_at THEN
'disconnected'
WHEN NOW() - workspace_agents.last_connected_at > INTERVAL '1 second' * $9 :: bigint THEN
'disconnected'
WHEN workspace_agents.last_connected_at IS NOT NULL THEN
'connected'
ELSE
NULL
END
)
) > 0
ELSE true
END
-- Authorize Filter clause will be injected below in GetAuthorizedWorkspaces
-- @authorize_filter
ORDER BY
last_used_at DESC
last_used_at DESC
LIMIT
CASE
WHEN $9 :: integer > 0 THEN
$9
END
CASE
WHEN $11 :: integer > 0 THEN
$11
END
OFFSET
$8
$10
`
type GetWorkspacesParams struct {
Deleted bool `db:"deleted" json:"deleted"`
Status string `db:"status" json:"status"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
OwnerUsername string `db:"owner_username" json:"owner_username"`
TemplateName string `db:"template_name" json:"template_name"`
TemplateIds []uuid.UUID `db:"template_ids" json:"template_ids"`
Name string `db:"name" json:"name"`
Offset int32 `db:"offset_" json:"offset_"`
Limit int32 `db:"limit_" json:"limit_"`
Deleted bool `db:"deleted" json:"deleted"`
Status string `db:"status" json:"status"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
OwnerUsername string `db:"owner_username" json:"owner_username"`
TemplateName string `db:"template_name" json:"template_name"`
TemplateIds []uuid.UUID `db:"template_ids" json:"template_ids"`
Name string `db:"name" json:"name"`
HasAgent string `db:"has_agent" json:"has_agent"`
AgentInactiveDisconnectTimeoutSeconds int64 `db:"agent_inactive_disconnect_timeout_seconds" json:"agent_inactive_disconnect_timeout_seconds"`
Offset int32 `db:"offset_" json:"offset_"`
Limit int32 `db:"limit_" json:"limit_"`
}
type GetWorkspacesRow struct {
@@ -6437,6 +6477,8 @@ func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams)
arg.TemplateName,
pq.Array(arg.TemplateIds),
arg.Name,
arg.HasAgent,
arg.AgentInactiveDisconnectTimeoutSeconds,
arg.Offset,
arg.Limit,
)