Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allows forcing/skipping calendar cache serving #18224

Merged
merged 7 commits into from
Dec 17, 2024

Conversation

zomars
Copy link
Member

@zomars zomars commented Dec 17, 2024

Folow up to #11928

What does this PR do?

This pull request introduces several enhancements and refactors to the calendar service, focusing on caching and availability fetching mechanisms. The key changes include the introduction of a new shouldServeCache parameter, refactoring of cache-related functions, and updates to various calendar service methods to incorporate these changes.

Enhancements to caching and availability fetching:

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

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?

Scenario 1

  • Have a team with a TeamFeature entry for both "calendar-cache" and "calendar-cache-serve"
  • Test out a booking normally
  • Test out a booking with ?cal.cache=false parameter. It should skip cache altogether.

Scenario 2

  • Have a team with a TeamFeature entry for both "calendar-cache"only.
  • Test out a booking normally
  • Test out a booking with ?cal.cache=true parameter. It should force cache serving.

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

Signed-off-by: Omar López <zomars@me.com>
@zomars zomars requested a review from a team as a code owner December 17, 2024 04:53
@github-actions github-actions bot added the ❗️ migrations contains migration files label Dec 17, 2024
@keithwillcode keithwillcode added core area: core, team members only foundation labels Dec 17, 2024
@dosubot dosubot bot added app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar ✨ feature New feature or request labels Dec 17, 2024
Copy link

vercel bot commented Dec 17, 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 17, 2024 4:04pm
calcom-web-canary ⬜️ Ignored (Inspect) Visit Preview Dec 17, 2024 4:04pm

Copy link
Contributor

github-actions bot commented Dec 17, 2024

E2E results are ready!

Copy link
Member Author

@zomars zomars left a comment

Choose a reason for hiding this comment

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

Ready for review

Comment on lines +514 to +517
async getFreeBusyResult(
args: FreeBusyArgs,
shouldServeCache?: boolean
): Promise<calendar_v3.Schema$FreeBusyResponse> {
Copy link
Member Author

Choose a reason for hiding this comment

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

Extracted to take advantage of early returns

args: FreeBusyArgs,
shouldServeCache?: boolean
): Promise<calendar_v3.Schema$FreeBusyResponse> {
if (shouldServeCache === false) return await this.fetchAvailability(args);
Copy link
Member Author

Choose a reason for hiding this comment

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

If the parameter is explicitly set to false we skip cache altogether

@@ -537,7 +544,8 @@ export default class GoogleCalendarService implements Calendar {
async getAvailability(
dateFrom: string,
dateTo: string,
selectedCalendars: IntegrationCalendar[]
selectedCalendars: IntegrationCalendar[],
shouldServeCache?: boolean
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not a fan to drilling but I couldn't find a cleaner way to pass this setting around.

externalId: calendarId,
},
});
const sc = await SelectedCalendarRepository.findByExternalId(credentialId, calendarId);
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to repo

Comment on lines +711 to +716
// Populate the cache back for the remaining calendars, if any
const remainingCalendars =
sc?.credential?.selectedCalendars.filter((sc) => sc.externalId !== calendarId) || [];
if (remainingCalendars.length > 0) {
await this.fetchAvailabilityAndSetCache(remainingCalendars);
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This fixes a concern that @hariombalhara exposed

@@ -136,51 +135,6 @@ const cleanIntegrationKeys = (
return rest;
};

// here I will fetch the page json file.
export const getCachedResults = async (
Copy link
Member Author

Choose a reason for hiding this comment

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

Dead code

@@ -4,6 +4,7 @@
**/
export type AppFlags = {
"calendar-cache": boolean;
"calendar-cache-serve": boolean;
Copy link
Member Author

Choose a reason for hiding this comment

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

Whether to serve the cache by default or not. Override-able via URL params. @keithwillcode

@@ -48,6 +48,7 @@ export const useSchedule = ({
const searchParams = useSearchParams();
const routedTeamMemberIds = searchParams ? getRoutedTeamMemberIdsFromSearchParams(searchParams) : null;
const skipContactOwner = searchParams ? searchParams.get("cal.skipContactOwner") === "true" : false;
const shouldServeCache = searchParams ? searchParams.get("cal.cache") === "true" : undefined;
Copy link
Member Author

Choose a reason for hiding this comment

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

Undefined will fallback to the feature flag for this specific team/org

@@ -33,8 +34,7 @@ import { UserRepository } from "@calcom/lib/server/repository/user";
import getSlots from "@calcom/lib/slots";
import prisma, { availabilityUserSelect } from "@calcom/prisma";
import { PeriodType, Prisma } from "@calcom/prisma/client";
import { SchedulingType } from "@calcom/prisma/enums";
import { BookingStatus } from "@calcom/prisma/enums";
import { BookingStatus, SchedulingType } from "@calcom/prisma/enums";
Copy link
Member Author

Choose a reason for hiding this comment

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

Sorted imports

Comment on lines 454 to 458
const shouldServeCache =
/** If we set the parameter use that, else check if the team has the feature enabled */
typeof _shouldServeCache === "boolean" || !teamId
? _shouldServeCache
: await featureRepo.checkIfTeamHasFeature(teamId, "calendar-cache-serve");
Copy link
Member Author

Choose a reason for hiding this comment

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

Here we decide if the we should serve cache or not

@@ -11,7 +11,8 @@ const getCalendarsEvents = async (
withCredentials: CredentialPayload[],
dateFrom: string,
dateTo: string,
selectedCalendars: SelectedCalendar[]
selectedCalendars: SelectedCalendar[],
shouldServeCache?: boolean
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this nullable? Seems like we should either just pass true or false.

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Undefined will fallback to the DB default. If we force a boolean value the fallback will never execute.

@@ -44,6 +44,7 @@ export async function getBusyTimes(params: {
})[]
| null;
bypassBusyCalendarTimes: boolean;
shouldServeCache?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this nullable? Seems like we should either just pass true or false.


export async function getShouldServeCache(shouldServeCache?: boolean | undefined, teamId?: number) {
if (typeof shouldServeCache === "boolean") return shouldServeCache;
if (!teamId) return undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not false here?

Copy link
Member Author

Choose a reason for hiding this comment

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

undefined has meaning in this feature.

Copy link
Member Author

Choose a reason for hiding this comment

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

Undefined means there's no preference. So the regular default behavior will apply.

zomars and others added 2 commits December 17, 2024 08:17
…erve/migration.sql

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
@@ -65,4 +65,15 @@ export class FeaturesRepository implements IFeaturesRepository {
throw err;
}
}
async checkIfTeamHasFeature(teamId: number, featureId: keyof AppFlags) {
try {
const teamFeature = await db.teamFeatures.findUnique({
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean?

Suggested change
const teamFeature = await db.teamFeatures.findUnique({
const teamFeature = await db.teamFeatures.findUniqueOrThrow({

Copy link
Member Author

Choose a reason for hiding this comment

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

Not throwing since we're expecting a boolean return value

Copy link
Contributor

@emrysal emrysal left a comment

Choose a reason for hiding this comment

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

Happy with this, let's get it merged.

@emrysal emrysal merged commit 2eb385a into main Dec 17, 2024
40 checks passed
@emrysal emrysal deleted the feat-calendar-cache-settings branch December 17, 2024 16:54
MuhammadAimanSulaiman pushed a commit to hit-pay/cal.com that referenced this pull request Jan 10, 2025
* feat: allows forcing/skipping calendar cache serving

Signed-off-by: Omar López <zomars@me.com>

* Update features.repository.ts

* Added to HNB

* type fixes

* Update packages/prisma/migrations/20241216000000_add_calendar_cache_serve/migration.sql

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* Update packages/prisma/zod-utils.ts

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* Update selectedCalendar.ts

---------

Signed-off-by: Omar López <zomars@me.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
MuhammadAimanSulaiman pushed a commit to hit-pay/cal.com that referenced this pull request Feb 20, 2025
* feat: allows forcing/skipping calendar cache serving

Signed-off-by: Omar López <zomars@me.com>

* Update features.repository.ts

* Added to HNB

* type fixes

* Update packages/prisma/migrations/20241216000000_add_calendar_cache_serve/migration.sql

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* Update packages/prisma/zod-utils.ts

Co-authored-by: Keith Williams <keithwillcode@gmail.com>

* Update selectedCalendar.ts

---------

Signed-off-by: Omar López <zomars@me.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app-store area: app store, apps, calendar integrations, google calendar, outlook, lark, apple calendar core area: core, team members only ✨ feature New feature or request foundation high-risk Requires approval by Foundation team ❗️ migrations contains migration files ready-for-e2e
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants