Files
calendar/packages/features/flags/server/utils.ts
T
d294a74aad feat: Populate gCal calendar cache via webhooks (#11928)
* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Update CalendarService.ts

* Type fixes

* WIP

* fix: improve cache hits

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Update CalendarService.ts

* Feedback

* Update CalendarService.ts

* Update CalendarService.ts

* Update _router.ts

* feedback

* WIP

* WIP

* Update schema.prisma

* feedback

* typefixes

* Update Calendar.d.ts

* fix: watches when adding a calendar

* Discard changes to packages/app-store/googlecalendar/api/add.ts

* WIP

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

* WIP

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

* WP

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

* Update calendar.ts

* Update calendar.ts

* Update callback.ts

* Update callback.ts

* Conflicts

* WIP

* WIP

* Update CalendarService.ts

* Cleanup

* Discard changes to packages/features/settings/layouts/SettingsLayout.tsx

* Update calendar-cache.repository.ts

* WIP

* Update getSelectedCalendarsToWatch.sql

* WIP

* Update CalendarService.ts

* Cleanup

* Discard changes to packages/app-store/googlecalendar/lib/CalendarService.ts

* Create CalendarService.wip.ts

* WIP

* Update CalendarService.ts

* Update getSelectedCalendarsToWatch.sql

* Delete CalendarService.wip.ts

* test updates

* cleanup

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

* Update CalendarService.test.ts

* Update CalendarService.ts

* type fixes

* Update OAuthManager.ts

* Update CalendarService.ts

* Almost there

* Update CalendarService.test.ts

* Update calendar.ts

* Update callback.ts

* Update toggleFeatureFlag.handler.ts

* fix: feedback

* Update getSelectedCalendarsToWatch.sql

* Fix unit tests

---------

Signed-off-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2024-11-15 14:59:37 -03:00

73 lines
1.9 KiB
TypeScript

import type { PrismaClient } from "@calcom/prisma";
import type { AppFlags } from "../config";
// This is a temporary cache to avoid hitting the database on every lambda invocation
let TEMP_CACHE: AppFlags | null = null;
export async function getFeatureFlagMap(prisma: PrismaClient) {
// If we've already fetched the flags, return them
if (TEMP_CACHE) return TEMP_CACHE;
const flags = await prisma.feature.findMany({
orderBy: { slug: "asc" },
cacheStrategy: { swr: 300, ttl: 300 },
});
TEMP_CACHE = flags.reduce((acc, flag) => {
acc[flag.slug as keyof AppFlags] = flag.enabled;
return acc;
}, {} as AppFlags);
return TEMP_CACHE;
}
interface CacheEntry {
value: boolean; // adapt to other supported value types in the future
expiry: number;
}
interface CacheOptions {
ttl: number; // time in ms
}
const featureFlagCache = new Map<keyof AppFlags, CacheEntry>();
const isExpired = (entry: CacheEntry): boolean => {
return Date.now() > entry.expiry;
};
export const getFeatureFlag = async (
prisma: PrismaClient,
slug: keyof AppFlags,
options: CacheOptions = { ttl: 5 * 60 * 1000 }
): Promise<boolean> => {
// pre-compute all app flags, each one will independelty reload it's own state after expiry.
if (featureFlagCache.size === 0) {
const flags = await prisma.feature.findMany({ orderBy: { slug: "asc" } });
flags.forEach((flag) => {
featureFlagCache.set(flag.slug as keyof AppFlags, {
value: flag.enabled,
expiry: Date.now() + options.ttl,
});
});
}
const cacheEntry = featureFlagCache.get(slug);
if (cacheEntry && !isExpired(cacheEntry)) {
return cacheEntry.value;
}
const flag = await prisma.feature.findUnique({
where: {
slug,
},
});
const isEnabled = Boolean(flag && flag.enabled);
const expiry = Date.now() + options.ttl;
featureFlagCache.set(slug, { value: isEnabled, expiry });
return isEnabled;
};