Skip to content

Commit 886d3f1

Browse files
Merge pull request #188 from rajputomsingh/fix/redis-cache-reliability
fix(redis): improve cache reliability and health monitoring
2 parents 994a4fb + 51579ca commit 886d3f1

2 files changed

Lines changed: 347 additions & 39 deletions

File tree

app/api/health/redis/route.ts

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,102 @@
11
// app/api/health/redis/route.ts
2-
import { NextResponse } from "next/server";
3-
import { redis } from "@/lib/redis";
2+
import { NextResponse } from 'next/server';
3+
import { redis, getHealth } from '@/lib/redis';
4+
5+
export const dynamic = 'force-dynamic';
46

57
export async function GET() {
8+
const health = getHealth();
9+
10+
// If Redis isn't initialized, return immediately
611
if (!redis) {
7-
return NextResponse.json({ status: "Redis not configured" }, { status: 503 });
12+
return NextResponse.json(
13+
{
14+
status: 'unavailable',
15+
initialized: false,
16+
error: 'Redis client not initialized',
17+
timestamp: new Date().toISOString(),
18+
},
19+
{ status: 503 }
20+
);
21+
}
22+
23+
// If circuit breaker is open, don't attempt ping
24+
if (health.circuitBreakerOpen) {
25+
return NextResponse.json(
26+
{
27+
status: 'unhealthy',
28+
connected: false,
29+
error: 'Circuit breaker is open',
30+
...health,
31+
timestamp: new Date().toISOString(),
32+
},
33+
{ status: 503 }
34+
);
835
}
936

37+
// Perform real connectivity check
38+
const startTime = Date.now();
39+
1040
try {
11-
await redis.ping();
12-
return NextResponse.json({ status: "healthy", timestamp: new Date().toISOString() });
41+
const pingResult = await Promise.race([
42+
redis.ping(),
43+
new Promise<null>((_, reject) =>
44+
setTimeout(
45+
() => reject(new Error('Ping timed out after 3s')),
46+
3000
47+
)
48+
),
49+
]);
50+
51+
const latency = Date.now() - startTime;
52+
53+
if (pingResult === 'PONG') {
54+
return NextResponse.json(
55+
{
56+
status: 'healthy',
57+
connected: true,
58+
latency,
59+
...health,
60+
timestamp: new Date().toISOString(),
61+
},
62+
{ status: 200 }
63+
);
64+
}
65+
66+
return NextResponse.json(
67+
{
68+
status: 'degraded',
69+
connected: false,
70+
latency,
71+
error: `Unexpected ping response: ${typeof pingResult}`,
72+
...health,
73+
timestamp: new Date().toISOString(),
74+
},
75+
{ status: 503 }
76+
);
1377
} catch (error) {
14-
return NextResponse.json({ status: "unhealthy", error: String(error) }, { status: 503 });
78+
const latency = Date.now() - startTime;
79+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
80+
81+
let status: string = 'unhealthy';
82+
let diagnostic = errorMessage;
83+
84+
if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('getaddrinfo')) {
85+
diagnostic = `DNS resolution failed: ${errorMessage}`;
86+
} else if (errorMessage.includes('timed out')) {
87+
status = 'degraded';
88+
}
89+
90+
return NextResponse.json(
91+
{
92+
status,
93+
connected: false,
94+
latency,
95+
error: diagnostic,
96+
...health,
97+
timestamp: new Date().toISOString(),
98+
},
99+
{ status: 503 }
100+
);
15101
}
16102
}

0 commit comments

Comments
 (0)