Skip to content

perf: /router endpoint perf improvement#18366

Merged
hariombalhara merged 8 commits into
mainfrom
routing-perf
Dec 27, 2024
Merged

perf: /router endpoint perf improvement#18366
hariombalhara merged 8 commits into
mainfrom
routing-perf

Conversation

@hariombalhara
Copy link
Copy Markdown
Member

@hariombalhara hariombalhara commented Dec 24, 2024

What does this PR do?

  • Using possibly faster findUnique for form query instead of findFirst
  • Abstracted out handleResponse from response.handler.ts to be reused in /router - It allows already available form to be passed directly to handleResponse and avoids one sequential query to DB.
  • Passing orgId directly to findTeamMembersMatchingAttributeLogic which helps in restricting the number of records being queried in attributes related tables.
  • Completely different querying approach for getAttributesAssignmentData avoiding some queries in Prisma and using some in memory calculations.
  • Also added /router endpoint to vercel.json with more memory to give it more vCPUs
  • Moved /router and trpc /response endpoint out of app-store as it was not allowing to use the repositories. Prisma was getting imported client side - Note: Moving /router to app-router can be done later.
  • Already computed timings(and a few more) would be logged in Axiom now. Later to be moved to Sentry.
    Sample
    Server-Timing formQuery;dur=4.965374946594238, profileEnrichment;dur=1.2969579696655273, getSerializableForm;dur=14.026041984558105, ttgetAttributesQueryBuilderConfigHavingListofLabels;dur=0.6570830345153809, ttTeamMembersMatchingAttributeLogic;dur=23.702916860580444, ttGetAttributesForLogic;dur=292.05258297920227

Improvement seen locally:

  • With 2000 members in Acme and half of them being part of the Insights team, querying time went from 442ms(minimum) to 271ms(minimum). The improvements should be more visible with production data which has much much higher number of records. Note that even with 2000 members the time that we are optimizing is still low because total number of records across different tables are very few compared to production data.

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Test Preview of Routing Form
  • /router endpoint should also work
  • A regular routing form submission should also work

Followup

  • A teamMembershipId column in attributeToUser could possibly save some querying time, if in-memory computation for orgMembershipId to userId doesn't work

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 24, 2024

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "Add stats and allow showing embed without loader". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@vercel
Copy link
Copy Markdown

vercel Bot commented Dec 24, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
cal ⬜️ Ignored (Inspect) Visit Preview Dec 27, 2024 7:09am
calcom-web-canary ⬜️ Ignored (Inspect) Visit Preview Dec 27, 2024 7:09am

@keithwillcode keithwillcode added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Dec 24, 2024
@hariombalhara hariombalhara changed the title Add stats and allow showing embed without loader perf: /router endpoint perf improvement Dec 24, 2024
);

// TODO: To be done using sentry tracing
console.log("Server-Timing", getServerTimingHeader(timeTaken));
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

timeTaken is already being computed, so I will just use the same approach for now for quick release. I will later move it to Sentry.

Comment on lines -134 to -138
const { createContext } = await import("@calcom/trpc/server/createContext");
const ctx = await createContext(context);

const { default: trpcRouter } = await import("@calcom/app-store/routing-forms/trpc/_router");
const caller = trpcRouter.createCaller(ctx);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Avoid using another trpcHandler and instead use the utility directly.

Also, needed to do this so that I can easily pass on already queried form to handleResponse and avoid repeat querying of same data

@github-actions github-actions Bot added the ❗️ migrations contains migration files label Dec 24, 2024
include: {
team: {
select: {
parentId: true,
Copy link
Copy Markdown
Member Author

@hariombalhara hariombalhara Dec 24, 2024

Choose a reason for hiding this comment

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

New requirement, it was already queried in /router endpoint for some other requirement


const form = await prisma.app_RoutingForms_Form.findFirst({
async function findFormById(formId: string, prisma: AppPrisma) {
return await prisma.app_RoutingForms_Form.findUnique({
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Using findUnique instead of findFirst

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 24, 2024

E2E results are ready!

Comment thread apps/web/next.config.js
Comment on lines -296 to -298
source: "/router/:path*",
destination: "/apps/routing-forms/router/:path*",
},
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Rewrite not needed because /router is actually a route now

Comment on lines 25 to 27
form: z.string(),
slug: z.string(),
pages: z.array(z.string()),
})
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Slug pages was there because it was earlier under app-store. Now it is not needed.

const { form: formId, embed, ...fieldsResponses } = queryParsed.data;
const { currentOrgDomain } = orgDomainConfig(context.req);

let timeTaken: Record<string, number | null> = {};
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Commented at other places as well but comment here as well. Time Taken is an existing approach that I am adding more data on. This later needs to move to Sentry performance tracing

const result = await caller.public.response({
formId: form.id,
const result = await handleResponse({
form: serializableForm,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Passing already queried form now.

: null;

const teamMembersMatchingAttributeLogicWithResult =
formTeamId && formOrgId
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Team Members matching logic is applicable only for organization

Comment thread apps/web/vercel.json
"pages/api/trpc/appRoutingForms/[trpc].ts": {
"memory": 2048
},
"pages/router/embed.tsx": {
Copy link
Copy Markdown
Member Author

@hariombalhara hariombalhara Dec 26, 2024

Choose a reason for hiding this comment

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

Not sure if page route will work but I am assuming it would.

Giving it more vCPUs, because there are a lot of computations that happen through this route's getServerSideProps -> handleResponse -> findTeamMembersMatchingAttributeLogic

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We could add non embed route as well later but for now this is necessary.

@hariombalhara hariombalhara marked this pull request as ready for review December 26, 2024 06:25
@graphite-app graphite-app Bot requested review from a team December 26, 2024 06:25
@dosubot dosubot Bot added performance area: performance, page load, slow, slow endpoints, loading screen, unresponsive routing-forms area: routing forms, routing, forms labels Dec 26, 2024
@graphite-app
Copy link
Copy Markdown

graphite-app Bot commented Dec 26, 2024

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (12/26/24)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add foundation team as reviewer" took an action on this PR • (12/26/24)

1 reviewer was added to this PR based on Keith Williams's automation.

@Udit-takkar Udit-takkar added this to the v4.9 milestone Dec 26, 2024
@PeerRich PeerRich added the High priority Created by Linear-GitHub Sync label Dec 26, 2024
Copy link
Copy Markdown
Contributor

@Udit-takkar Udit-takkar left a comment

Choose a reason for hiding this comment

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

Screen.Recording.2024-12-26.at.1.53.45.PM.mov

Whenever i type a letter the input looses focus and i have to click again to type the next letter.

Not sure if this bug was introduced in this PR

@hariombalhara
Copy link
Copy Markdown
Member Author

Screen.Recording.2024-12-26.at.1.53.45.PM.mov
Whenever i type a letter the input looses focus and i have to click again to type the next letter.

Not sure if this bug was introduced in this PR

That is weird. I don't think I touched anything in there.

Copy link
Copy Markdown
Contributor

@keithwillcode keithwillcode left a comment

Choose a reason for hiding this comment

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

Why aren't we using the Sentry perf tracing instead of log messages?

Copy link
Copy Markdown
Contributor

@Udit-takkar Udit-takkar left a comment

Choose a reason for hiding this comment

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

LGTM.

This issue #18366 (review) is not related to this PR

@hariombalhara
Copy link
Copy Markdown
Member Author

@keithwillcode Time taken was already computed earlier,I am just logging thode in this PR and added 2 more cases I believe

Will tackle move to sentry in a followup

@hariombalhara hariombalhara requested a review from a team December 27, 2024 07:11
@hariombalhara hariombalhara enabled auto-merge (squash) December 27, 2024 08:51
@hariombalhara hariombalhara merged commit b5bec79 into main Dec 27, 2024
@hariombalhara hariombalhara deleted the routing-perf branch December 27, 2024 08:56
MuhammadAimanSulaiman pushed a commit to hit-pay/cal.com that referenced this pull request Jan 10, 2025
MuhammadAimanSulaiman pushed a commit to hit-pay/cal.com that referenced this pull request Feb 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO High priority Created by Linear-GitHub Sync ❗️ migrations contains migration files performance area: performance, page load, slow, slow endpoints, loading screen, unresponsive ready-for-e2e routing-forms area: routing forms, routing, forms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants