Skip to content

Allow filtering Duo workflows by status group and goal/title

What does this MR do and why?

Allow filtering Duo workflows by their status_group or through a fuzzy search against their goal or definition (aka title).

This is needed so users are able to choose how they want to see in the sessions page.

References

Related to #571931 (closed)

GraphQL details

GraphQL Query
query getAgentFlows(
  $projectPath: ID!,
  $sort: DuoWorkflowsWorkflowSort,
  $statusGroup: DuoWorkflowStatusGroup,
  $type: String
) {
  project(fullPath: $projectPath) {
    id
    duoWorkflowWorkflows(
      projectPath: $projectPath
      sort: $sort
      statusGroup: $statusGroup
      type: $type
    ) {
      pageInfo {
        startCursor
        endCursor
        hasNextPage
        hasPreviousPage
      }
      edges {
        node {
          id
          goal
          workflowDefinition
          status
          statusName
          statusGroup
        }
      }
    }
  }
}
Variables
{
  "projectPath": "gitlab-duo/test",
  "sort": "STATUS_DESC",
  "statusGroup": null,
  "type": "code_review/experimental"
}

SQL query plans

When fuzzy searching by title or goal

Raw SQL
SELECT 
  "duo_workflows_workflows".*
FROM "duo_workflows_workflows" 
WHERE 
  "duo_workflows_workflows"."project_id" = 278964 
  AND "duo_workflows_workflows"."workflow_definition" != 'chat' 
  AND "duo_workflows_workflows"."environment" = 2 
  AND (
      "duo_workflows_workflows"."workflow_definition" ILIKE '%code%' 
      AND "duo_workflows_workflows"."workflow_definition" ILIKE '%review%' OR "duo_workflows_workflows"."goal" ILIKE '%code%' 
      AND "duo_workflows_workflows"."goal" ILIKE '%review%'
  )
ORDER BY 
  "duo_workflows_workflows"."created_at" DESC
SQL plan without new index

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44288/commands/135743

 Sort  (cost=9441.74..9441.76 rows=8 width=338) (actual time=2466.257..2466.261 rows=19 loops=1)
   Sort Key: duo_workflows_workflows.created_at DESC
   Sort Method: quicksort  Memory: 28kB
   Buffers: shared hit=7 read=5765 dirtied=648
   WAL: records=699 fpi=648 bytes=5146939
   I/O Timings: read=2398.086 write=0.000
   ->  Index Scan using index_duo_workflows_workflows_on_project_id on public.duo_workflows_workflows  (cost=0.29..9441.62 rows=8 width=338) (actual time=1063.636..2466.153 rows=19 loops=1)
         Index Cond: (duo_workflows_workflows.project_id = 278964)
         Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.environment = 2) AND (((duo_workflows_workflows.workflow_definition ~~* '%code%'::text) AND (duo_workflows_workflows.workflow_definition ~~* '%review%'::text)) OR ((duo_workflows_workflows.goal ~~* '%code%'::text) AND (duo_workflows_workflows.goal ~~* '%review%'::text))))
         Rows Removed by Filter: 21350
         Buffers: shared hit=4 read=5765 dirtied=648
         WAL: records=699 fpi=648 bytes=5146939
         I/O Timings: read=2398.086 write=0.000
Settings: effective_cache_size = '472585MB', jit = 'off', random_page_cost = '1.5', seq_page_cost = '4', work_mem = '100MB'
SQL plan with new index

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44420/commands/136146

Index Scan using index_duo_workflows_workflows_project_environment_created_at on public.duo_workflows_workflows  (cost=0.42..7753.65 rows=10 width=338) (actual time=0.294..20.398 rows=269 loops=1)
   Index Cond: ((duo_workflows_workflows.project_id = 278964) AND (duo_workflows_workflows.environment = 2))
   Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (((duo_workflows_workflows.workflow_definition ~~* '%code%'::text) AND (duo_workflows_workflows.workflow_definition ~~* '%review%'::text)) OR ((duo_workflows_workflows.goal ~~* '%code%'::text) AND (duo_workflows_workflows.goal ~~* '%review%'::text))))
   Rows Removed by Filter: 8438
   Buffers: shared hit=8599 read=46 dirtied=489
   WAL: records=526 fpi=489 bytes=3877346
   I/O Timings: read=1.322 write=0.000
Settings: random_page_cost = '1.5', seq_page_cost = '4', effective_cache_size = '472585MB', jit = 'off', work_mem = '100MB'

When filtering by status_group

Raw SQL
SELECT 
  "duo_workflows_workflows".*
FROM "duo_workflows_workflows"
WHERE 
  "duo_workflows_workflows"."project_id" = 278964 
  AND "duo_workflows_workflows"."workflow_definition" != 'chat' 
  AND "duo_workflows_workflows"."environment" = 2 
  AND "duo_workflows_workflows"."status" = 5
ORDER BY 
  "duo_workflows_workflows"."created_at" DESC
SQL plan

https://postgres.ai/console/gitlab/gitlab-production-main/sessions/44288/commands/135745

 Sort  (cost=1257.65..1257.74 rows=39 width=338) (actual time=21.865..21.869 rows=0 loops=1)
   Sort Key: duo_workflows_workflows.created_at DESC
   Sort Method: quicksort  Memory: 25kB
   Buffers: shared hit=470 read=29
   I/O Timings: read=17.774 write=0.000
   ->  Bitmap Heap Scan on public.duo_workflows_workflows  (cost=303.71..1256.62 rows=39 width=338) (actual time=21.847..21.851 rows=0 loops=1)
         Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.environment = 2))
         Rows Removed by Filter: 484
         Buffers: shared hit=467 read=29
         I/O Timings: read=17.774 write=0.000
         ->  BitmapAnd  (cost=303.71..303.71 rows=450 width=0) (actual time=20.151..20.154 rows=0 loops=1)
               Buffers: shared hit=34 read=29
               I/O Timings: read=17.774 write=0.000
               ->  Bitmap Index Scan using idx_workflows_status_updated_at_id  (cost=0.00..90.71 rows=3039 width=0) (actual time=18.479..18.479 rows=3045 loops=1)
                     Index Cond: (duo_workflows_workflows.status = 5)
                     Buffers: shared hit=3 read=29
                     I/O Timings: read=17.774 write=0.000
               ->  Bitmap Index Scan using index_duo_workflows_workflows_on_project_id  (cost=0.00..212.72 rows=21324 width=0) (actual time=1.498..1.498 rows=21369 loops=1)
                     Index Cond: (duo_workflows_workflows.project_id = 278964)
                     Buffers: shared hit=31
                     I/O Timings: read=0.000 write=0.000
Settings: jit = 'off', random_page_cost = '1.5', seq_page_cost = '4', work_mem = '100MB', effective_cache_size = '472585MB'
SQL plan with new index

https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44420/commands/136148

 Sort  (cost=29.37..29.38 rows=1 width=338) (actual time=27.859..27.861 rows=0 loops=1)
   Sort Key: duo_workflows_workflows.created_at DESC
   Sort Method: quicksort  Memory: 25kB
   Buffers: shared hit=286 read=12 dirtied=9
   WAL: records=15 fpi=9 bytes=43767
   I/O Timings: read=26.094 write=0.000
   ->  Index Scan using idx_workflows_status_updated_at_id on public.duo_workflows_workflows  (cost=0.42..29.36 rows=1 width=338) (actual time=27.846..27.846 rows=0 loops=1)
         Index Cond: (duo_workflows_workflows.status = 1)
         Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.project_id = 278964) AND (duo_workflows_workflows.environment = 2))
         Rows Removed by Filter: 26
         Buffers: shared hit=283 read=12 dirtied=9
         WAL: records=15 fpi=9 bytes=43767
         I/O Timings: read=26.094 write=0.000
Settings: effective_cache_size = '472585MB', jit = 'off', work_mem = '100MB', random_page_cost = '1.5', seq_page_cost = '4'

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Wanderson Policarpo

Merge request reports

Loading