@@ -19,6 +19,7 @@ import type { CredentialPayload, CredentialWithAppName } from "@calcom/types/Cre
1919import type { EventResult } from "@calcom/types/EventManager" ;
2020
2121const log = logger . getChildLogger ( { prefix : [ "CalendarManager" ] } ) ;
22+ let coldStart = true ;
2223
2324export const getCalendarCredentials = ( credentials : Array < CredentialPayload > ) => {
2425 const calendarCredentials = getApps ( credentials )
@@ -183,48 +184,71 @@ export const getCachedResults = async (
183184 */
184185const getNextCache = async ( username : string , month : string ) : Promise < EventBusyDate [ ] [ ] > => {
185186 let localCache : EventBusyDate [ ] [ ] = [ ] ;
187+ const { NODE_ENV } = process . env ;
188+ const cacheDir = `${ NODE_ENV === "development" ? NODE_ENV : process . env . BUILD_ID } ` ;
189+ const baseUrl = `${ WEBAPP_URL } /_next/data/${ cacheDir } /en` ;
190+ const url = `${ baseUrl } /${ username } /calendar-cache/${ month } .json?user=${ username } &month=${ month } ` ;
186191 try {
187- const { NODE_ENV } = process . env ;
188- const cacheDir = `${ NODE_ENV === "development" ? NODE_ENV : process . env . BUILD_ID } ` ;
189- const baseUrl = `${ WEBAPP_URL } /_next/data/${ cacheDir } /en` ;
190- console . log ( `${ baseUrl } /${ username } /calendar-cache/${ month } .json?user=${ username } &month=${ month } ` ) ;
191- localCache = await fetch (
192- `${ baseUrl } /${ username } /calendar-cache/${ month } .json?user=${ username } &month=${ month } `
193- )
192+ localCache = await fetch ( url )
194193 . then ( ( r ) => r . json ( ) )
195194 . then ( ( json ) => json ?. pageProps ?. results ) ;
196- // No need to wait for this, the purpose is to force re-validation every second as indicated
197- // in page getStaticProps.
198- fetch ( `${ baseUrl } /${ username } /calendar-cache/${ month } ` ) . catch ( console . log ) ;
199195 } catch ( e ) {
200- log . warn ( e ) ;
196+ log . warn ( url , e ) ;
201197 }
202198 return localCache ;
203199} ;
200+ /**
201+ * Get months between given dates
202+ * @returns ["2023-04", "2024-05"]
203+ */
204+ const getMonths = ( dateFrom : string , dateTo : string ) : string [ ] => {
205+ const months : string [ ] = [ dayjs ( dateFrom ) . format ( "YYYY-MM" ) ] ;
206+ for (
207+ let i = 1 ;
208+ dayjs ( dateFrom ) . add ( i , "month" ) . isBefore ( dateTo ) ||
209+ dayjs ( dateFrom ) . add ( i , "month" ) . isSame ( dateTo , "month" ) ;
210+ i ++
211+ ) {
212+ months . push ( dayjs ( dateFrom ) . add ( i , "month" ) . format ( "YYYY-MM" ) ) ;
213+ }
214+ return months ;
215+ } ;
204216
217+ const createCalendarCachePage = ( username : string , month : string ) : void => {
218+ // No need to wait for this, the purpose is to force re-validation every second as indicated
219+ // in page getStaticProps.
220+ fetch ( `${ WEBAPP_URL } /${ username } /calendar-cache/${ month } ` ) . catch ( console . log ) ;
221+ } ;
205222export const getBusyCalendarTimes = async (
206223 username : string ,
207224 withCredentials : CredentialPayload [ ] ,
208225 dateFrom : string ,
209- dateTo : string
226+ dateTo : string ,
227+ selectedCalendars : SelectedCalendar [ ]
210228) => {
211229 let results : EventBusyDate [ ] [ ] = [ ] ;
212- if ( dayjs ( dateFrom ) . isSame ( dayjs ( dateTo ) , "month" ) ) {
213- results = await getNextCache ( username , dayjs ( dateFrom ) . format ( "YYYY-MM" ) ) ;
214- } else {
215- // if dateFrom and dateTo is from different months get cache by each month
216- const months : string [ ] = [ dayjs ( dateFrom ) . format ( "YYYY-MM" ) ] ;
217- for (
218- let i = 1 ;
219- dayjs ( dateFrom ) . add ( i , "month" ) . isBefore ( dateTo ) ||
220- dayjs ( dateFrom ) . add ( i , "month" ) . isSame ( dateTo , "month" ) ;
221- i ++
222- ) {
223- months . push ( dayjs ( dateFrom ) . add ( i , "month" ) . format ( "YYYY-MM" ) ) ;
230+ const months = getMonths ( dateFrom , dateTo ) ;
231+ try {
232+ if ( coldStart ) {
233+ results = await getCachedResults ( withCredentials , dateFrom , dateTo , selectedCalendars ) ;
234+ logger . info ( "Generating calendar cache in background" ) ;
235+ // on cold start the calendar cache page generated in the background
236+ Promise . all ( months . map ( ( month ) => createCalendarCachePage ( username , month ) ) ) ;
237+ } else {
238+ if ( months . length === 1 ) {
239+ results = await getNextCache ( username , dayjs ( dateFrom ) . format ( "YYYY-MM" ) ) ;
240+ } else {
241+ // if dateFrom and dateTo is from different months get cache by each month
242+ const data : EventBusyDate [ ] [ ] [ ] = await Promise . all (
243+ months . map ( ( month ) => getNextCache ( username , month ) )
244+ ) ;
245+ results = data . flat ( 1 ) ;
246+ }
224247 }
225- const data : EventBusyDate [ ] [ ] [ ] = await Promise . all ( months . map ( ( month ) => getNextCache ( username , month ) ) ) ;
226- results = data . flat ( 1 ) ;
248+ } catch ( e ) {
249+ logger . warn ( e ) ;
227250 }
251+ coldStart = false ;
228252 return results . reduce ( ( acc , availability ) => acc . concat ( availability ) , [ ] ) ;
229253} ;
230254
0 commit comments