Skip to content

Conversation

ZedLi
Copy link
Collaborator

@ZedLi ZedLi commented Aug 29, 2025

Description

A proof of concept at using sqlite to load the various filter options in session recordings page. Previously, we were loading all session recordings to then filter down the various filter options we need which takes a huge amount of time just returning all the data to filter.

This PR has a few notable changes:

  1. A simple attempt at establishing a pattern for using SELECT statements. This will be useful in the future for joins/subquery support.
  2. Expanded usage of searching to be able to pass instead of just a string, an object that lets a consumer choose which columns to search on.
  3. Decouple our filters from being loaded from the route model hook which is a departure from our convention. This has the benefit of actually letting the page first load and having the filters load async so the page doesn't wait for the filters to finish. This is also much faster to query for each individual filter option from SQLite rather than returning all data to filter in application code.
    • Having the queries be async does have some downsides in the scenario where there's a lot of filter options and a user might be waiting for the options to load if they're fast on clicking them but that also means the user wasn't waiting for filter options just for the page to load

Screenshots (if appropriate)

How to Test

Use this cluster and try loading session recordings compared to before this PR.

Checklist

  • I have added before and after screenshots for UI changes
  • I have added JSON response output for API changes
  • I have added steps to reproduce and test for bug fixes in the description
  • I have commented on my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a11y-tests label to run a11y audit tests if needed

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.
  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • If applicable, I've documented the impact of any changes to security controls.
    Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

@ZedLi ZedLi self-assigned this Aug 29, 2025
Copy link

vercel bot commented Aug 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
boundary-ui Ready Ready Preview Comment Oct 2, 2025 10:05pm
boundary-ui-desktop Ready Ready Preview Comment Oct 2, 2025 10:05pm

@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from bdf1081 to a2d70f7 Compare September 2, 2025 20:36
@ZedLi ZedLi force-pushed the llb/migrate-to-sqlite branch from 470e1fc to a2b2088 Compare September 2, 2025 21:00
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from a2d70f7 to 3e883c8 Compare September 2, 2025 21:03
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from 3e883c8 to 616202f Compare September 2, 2025 21:45
@ZedLi ZedLi force-pushed the llb/migrate-to-sqlite branch from 94a5676 to 25f015b Compare September 3, 2025 15:41
Base automatically changed from llb/migrate-to-sqlite to main September 3, 2025 16:49
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from 616202f to 24a3df0 Compare September 3, 2025 17:47
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from 24a3df0 to 38cb9e0 Compare September 8, 2025 22:12
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from 38cb9e0 to 9595de1 Compare September 16, 2025 21:41
@ZedLi ZedLi marked this pull request as ready for review September 17, 2025 22:53
@ZedLi ZedLi requested a review from a team as a code owner September 17, 2025 22:53
@ZedLi ZedLi force-pushed the use-sqlite-for-filters-session-recording branch from 9595de1 to 62b53a5 Compare September 24, 2025 23:45
Copy link
Collaborator

@hashicc hashicc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how these filters are now on-demand. The addition of search per column I can see being handy in other cases, too. Could the this.store.query() api for select reference in terms of the model attributes instead of columns since the mapping currently exists?

Also could returnRawData option be removed and the return of raw data is implied when distinct is used as a special case? returnRawData and pushToStore: false are similar and I'm wondering if having raw data opens up the result sets: pojos[], models[], rawData[], raw data being the one stands out because it's shape will be in terms of sql output

Comment on lines +173 to +175
if (distinctColumns.length > 0) {
selectColumns = `DISTINCT ${distinctColumns.map(({ field }) => field).join(', ')}`;
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a valid case to have a mix of distinct and regular columns selected? If it isn't, maybe an error could be thrown?

);
conditions.push(searchConditions);
}
function constructSelectClause(select = [{ field: '*' }], tableName) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it easier to use the model mapping and have selects expressed in terms of the model attributes and mapped to the underlying column? It feels like the outer api is starting to blend between the model/attributes and row/columns.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah you're right, this is a little leaky. I could make a reverse mapping of modelMapping (since it currently goes from column to JSON path) and use that so we don't have to be aware of the columns

@ZedLi
Copy link
Collaborator Author

ZedLi commented Oct 2, 2025

Also could returnRawData option be removed and the return of raw data is implied when distinct is used as a special case? returnRawData and pushToStore: false are similar and I'm wondering if having raw data opens up the result sets: pojos[], models[], rawData[], raw data being the one stands out because it's shape will be in terms of sql output

This is actually an interesting point because I wasn't sure of the best way to go about this. I agree it's not great but my thinking was the use of returnRawData makes it explicit this is a special case and an escape hatch (that returns a rawData[] in your analogy which can be anything) rather than have it be a surprise based on the conditions of the query since before this addition, it would always return a representation of a model in some form (whether it's a model or a POJO of a model).

It does start feeling like we are having more escape hatches than I would like but to me this also forces a conscious decision that what you're getting back isn't a model.

Realistically I think this is a code smell and I was originally thinking if the better solution is to just not go through store.query and basically query sqlite directly. This requires a bit of exposing query generation or adding another intermediate layer/helper though. Any thoughts on that?

Copy link
Collaborator

@lisbet-alvarez lisbet-alvarez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i only have two general comments but looks good and a big improvement to filters!

uniqueMap.set(id, { id, name: projectName, parent_scope_id });
}
page: 1,
pageSize: 250,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also update the Dropdown component item limit from 500 to 250 to keep it consistent (since its used in desktop app too)?

userFilters: {
select: [
{ field: 'user_id', isDistinct: true },
{ field: 'user_name', isDistinct: true },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it complicate the select objects too much if it were changed so that isDistinct is only specified once since it looks like the parser only looks to see if at least one field isDistinct? Totally get if the object is structured this way for consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants