Apply hooks search filter before pagination#8368
Conversation
52be92b to
aef4cd2
Compare
There was a problem hiding this comment.
This feels like the right way to fix the given search issue, but the reason why we have separate HookGroups query is because it is fast.
We had to create a new HookGroups view specifically to make first page load fast - original query takes <300ms to respond with all groups.
Now, when we include hooks inside that is suddenly becomes much slower - takes ~6s to load
lotas
left a comment
There was a problem hiding this comment.
We cannot accept current changes as it would be a regression.
Plus having client-side only search doesn't help here.
We should probably think about implementing a server-side filtering, or only include nested hooks when search is present.
Another idea on top of my head would be to use different view for the search purposes
4191d78 to
d6f5b5e
Compare
|
Thanks for the review @lotas. Reworked this with server-side filtering:
|
|
hey @nitishagar thanks for the refactor, I think this a step in the right direction, since we remove the expensive nested hook loading. That said, I think we are still overloading listHookGroups with search behavior that does not match its natural ocntract. We filter for both hook group and hook id, but return only hook group. That shape existed mostly because current UI was optimized that way. I think a cleaner approach would be to introduce a dedicated hook search endpoint and add new UI element that would display filtered hooks.
|
b0fb28a to
c844c3f
Compare
c844c3f to
e696ea6
Compare
|
Hi @lotas, thanks for the detailed review. I've reworked the approach based on your feedback. What changed: Instead of including
Performance: Initial page load is unchanged (still uses the fast groups-only query). Search triggers one efficient DB query instead of N+1 requests. Tests: Added DB function tests ( |
771054b to
34a8353
Compare
|
Thanks @lotas for the detailed feedback! The PR has been updated to address all your concerns: Server-side search implemented: Instead of client-side filtering, the PR now adds a dedicated
The previous client-side filtering approach has been removed entirely. The The CI failure ( |
34a8353 to
f98535d
Compare
| ].join('\n'), | ||
| }, async function(req, res) { | ||
| const { q } = req.query; | ||
| const hookRows = await this.db.fns.search_hooks(q || '', 1000, 0); |
There was a problem hiding this comment.
the new endpoint seems to silently cap at 1000 results, which feels like a footgun for future problems, even if this is documented. can we not use pagination here? we do that in other APIs... thanks!
|
Hey @petemoore Before I push the fix, wanted to sanity-check the shape with you, @lotas, and @matt-boris since there are a few design choices worth a sec of your time. Approach: use the existing
Also worth asking while we're here — should |
Refactor hooks search per review feedback: - New `search_hooks` DB function performs a single ILIKE query across hook_group_id and hook_id, returning full hook rows - New `GET /hooks/search?q=<term>` API endpoint (`searchHooks`) with pagination (default 100, max 1000, continuationToken) - `listHookGroups` keeps its fast contract (no search param) - GraphQL: new `searchHooks(query, continuationToken, limit)` returns `HookSearchResult`; `hookGroups` no longer takes `search` - UI: renders flat HooksListTable when `?search=` param is present with a Load More button; otherwise renders the normal HookGroupsTable Fixes taskcluster#7972
a608674 to
b602232
Compare
| method: 'get', | ||
| route: '/hooks/search', | ||
| name: 'searchHooks', | ||
| scopes: 'hooks:list-hooks:', |
There was a problem hiding this comment.
Existing listHooks() call expects hooks:list-hooks:<hookGroupId> scope, which means that we could allow users without necessary scope to see those in search output
Maybe having a hooks:search-hooks could be a right approach, or doing those checks in code to see if user role allows us accessing those hook groups

Summary
Fixes #7972.
Refactors the hooks search to use a dedicated
searchHooksAPI endpoint instead ofoverloading
listHookGroups. This was done per reviewer feedback in#8368 (comment).
Root cause: The previous approach added a
searchquery param tolistHookGroups,which didn't match its natural contract (it returns groups but was filtering by hook IDs).
The initial page load was also slow due to N+1 requests when fetching hook IDs per group.
Fix:
db/versions/0123.yml: addssearch_hooks(search_term_in, page_size, page_offset)—a single
ILIKEquery acrosshook_group_idandhook_id, returns full hook rowsGET /hooks/search?q=<term>API endpoint (searchHooks) — returns matchinghook definitions across all groups (same shape as
listHooks)listHookGroupsreverted to its clean contract (no search param, usesget_hook_groups())hookGroupsno longer takessearch; newsearchHooks(query: String!): [Hook]added?search=URL param is present, fetches fromsearchHooksand renders a flatHooksListTable; otherwise renders the normalHookGroupsTableInitial page load is fast (group IDs only). Searches trigger a single efficient DB query.
Changes
DB:
db/versions/0123.yml— newsearch_hooksfunction (replacesget_hook_groups_2)db/test/fns/hooks_test.js— tests forsearch_hooksdb/test/versions/0123_test.js— version smoke testAPI (
services/hooks):services/hooks/schemas/v1/search-hooks-response.yml— new schema (same shape aslistHooks)services/hooks/src/api.js— revertedlistHookGroups, addedsearchHooksat/hooks/searchservices/hooks/test/api_test.js— tests forsearchHooksGraphQL/Web-server:
services/web-server/src/graphql/Hooks.graphql— removedsearchfromhookGroups, addedsearchHooksservices/web-server/src/loaders/hooks.js— newhookSearchDataLoaderservices/web-server/src/resolvers/Hooks.js— newsearchHooksresolverUI:
ui/src/views/Hooks/ListHookGroups/hookGroups.graphql— simplified (no$search)ui/src/views/Hooks/ListHookGroups/searchHooks.graphql— new queryui/src/views/Hooks/ListHookGroups/index.jsx— two-mode renderingGenerated (from
yarn generate):generated/references.json,generated/db-schema.jsonlibraries/postgres/@types/fns.d.ts,db/fns.md,db/schema.md,db/versions/README.mdsearchHooksmethodTest Plan
cd db && yarn test— DB function tests passcd services/hooks && yarn test— API tests pass including newsearchHookssuite/hooks— groups table loads normally (no regression)PROJECTmatchesproject-releng)