courrier redis
This commit is contained in:
parent
b68993d68d
commit
3f415be882
27
app/api/redis/status/route.ts
Normal file
27
app/api/redis/status/route.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
import { getRedisClient } from '@/lib/redis';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API route to check Redis connection status
|
||||||
|
* Used for monitoring and debugging
|
||||||
|
*/
|
||||||
|
export async function GET() {
|
||||||
|
try {
|
||||||
|
const redis = getRedisClient();
|
||||||
|
const pong = await redis.ping();
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 'connected',
|
||||||
|
ping: pong,
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Redis status check failed:', error);
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 'error',
|
||||||
|
error: error instanceof Error ? error.message : String(error),
|
||||||
|
timestamp: new Date().toISOString()
|
||||||
|
}, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -500,24 +500,3 @@ export default function CourrierPage() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
|
||||||
// Initialize Redis connection early
|
|
||||||
const redisClient = getRedisClient();
|
|
||||||
const session = await getServerSession(context.req, context.res, authOptions);
|
|
||||||
|
|
||||||
let initialData = null;
|
|
||||||
if (session?.user?.id) {
|
|
||||||
// Try to get cached data
|
|
||||||
initialData = await getCachedEmailList(session.user.id, 'INBOX', 1, 20);
|
|
||||||
|
|
||||||
// Start prefetch in background without waiting
|
|
||||||
prefetchUserEmailData(session.user.id).catch(console.error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: {
|
|
||||||
initialData: initialData || null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -6,9 +6,13 @@ import { getServerSession } from "next-auth/next";
|
|||||||
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
|
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
|
||||||
import { Providers } from "@/components/providers";
|
import { Providers } from "@/components/providers";
|
||||||
import { LayoutWrapper } from "@/components/layout/layout-wrapper";
|
import { LayoutWrapper } from "@/components/layout/layout-wrapper";
|
||||||
|
import { warmupRedisCache } from '@/lib/services/prefetch-service';
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
|
// Warm up Redis connection during app initialization
|
||||||
|
warmupRedisCache().catch(console.error);
|
||||||
|
|
||||||
export default async function RootLayout({
|
export default async function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
|
|||||||
@ -98,7 +98,9 @@ export const useCourrier = () => {
|
|||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
// Still refresh in background for fresh data
|
// Still refresh in background for fresh data
|
||||||
refreshEmailsInBackground();
|
refreshEmailsInBackground(session.user.id, currentFolder, page, perPage).catch(err => {
|
||||||
|
console.error('Background refresh error:', err);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,9 +4,68 @@ import { getImapConnection, getEmails, getEmailContent } from './email-service';
|
|||||||
import {
|
import {
|
||||||
cacheEmailList,
|
cacheEmailList,
|
||||||
cacheEmailContent,
|
cacheEmailContent,
|
||||||
cacheImapSession
|
cacheImapSession,
|
||||||
|
getCachedEmailList,
|
||||||
|
getRedisClient
|
||||||
} from '@/lib/redis';
|
} from '@/lib/redis';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cached emails with timeout to ensure fast UI response
|
||||||
|
* If cache access takes longer than timeout, return null to use regular IMAP fetch
|
||||||
|
*/
|
||||||
|
export async function getCachedEmailsWithTimeout(
|
||||||
|
userId: string,
|
||||||
|
folder: string,
|
||||||
|
page: number,
|
||||||
|
perPage: number,
|
||||||
|
timeoutMs: number = 100
|
||||||
|
): Promise<any | null> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
console.log(`Cache access timeout for ${userId}:${folder}:${page}:${perPage}`);
|
||||||
|
resolve(null);
|
||||||
|
}, timeoutMs);
|
||||||
|
|
||||||
|
getCachedEmailList(userId, folder, page, perPage)
|
||||||
|
.then(result => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
if (result) {
|
||||||
|
console.log(`Using cached data for ${userId}:${folder}:${page}:${perPage}`);
|
||||||
|
resolve(result);
|
||||||
|
} else {
|
||||||
|
resolve(null);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
console.error('Error accessing cache:', err);
|
||||||
|
resolve(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh emails in background without blocking UI
|
||||||
|
* This allows the UI to show cached data immediately while refreshing in background
|
||||||
|
*/
|
||||||
|
export async function refreshEmailsInBackground(
|
||||||
|
userId: string,
|
||||||
|
folder: string = 'INBOX',
|
||||||
|
page: number = 1,
|
||||||
|
perPage: number = 20
|
||||||
|
): Promise<void> {
|
||||||
|
// Use setTimeout to ensure this runs after current execution context
|
||||||
|
setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
console.log(`Background refresh for ${userId}:${folder}:${page}:${perPage}`);
|
||||||
|
const freshData = await getEmails(userId, folder, page, perPage);
|
||||||
|
console.log(`Background refresh completed for ${userId}:${folder}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Background refresh error:', error);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefetch basic email data for faster initial loading
|
* Prefetch basic email data for faster initial loading
|
||||||
* This function should be called when a user logs in
|
* This function should be called when a user logs in
|
||||||
@ -110,10 +169,18 @@ export async function prefetchFolderEmails(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function warmupRedisCache() {
|
/**
|
||||||
// Ping Redis to establish connection early
|
* Warm up Redis connection to avoid cold starts
|
||||||
const redis = getRedisClient();
|
*/
|
||||||
await redis.ping();
|
export async function warmupRedisCache(): Promise<boolean> {
|
||||||
console.log('Redis connection warmed up');
|
try {
|
||||||
return true;
|
// Ping Redis to establish connection early
|
||||||
|
const redis = getRedisClient();
|
||||||
|
await redis.ping();
|
||||||
|
console.log('Redis connection warmed up');
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error warming up Redis:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user