Adjusted date range calculation to ensure data is displayed

This commit is contained in:
Tola Leng
2025-05-29 20:10:29 +08:00
parent d4d4040cc8
commit 0562adbef8
3 changed files with 87 additions and 117 deletions
+57 -68
View File
@@ -2,29 +2,24 @@
import { pb } from '@/lib/pocketbase';
import { UptimeData } from '@/types/service.types';
// Simple in-memory cache to avoid excessive requests
const uptimeCache = new Map<string, {
data: UptimeData[],
timestamp: number,
expiresIn: number
}>();
// Cache time-to-live in milliseconds
const CACHE_TTL = 15000; // 15 seconds
const CACHE_TTL = 3000; // 3 seconds for faster updates
export const uptimeService = {
async recordUptimeData(data: UptimeData): Promise<void> {
try {
console.log(`Recording uptime data for service ${data.serviceId}: Status ${data.status}, Response time: ${data.responseTime}ms`);
// Create a custom request options object to disable auto-cancellation
const options = {
$autoCancel: false, // Disable auto-cancellation for this request
$cancelKey: `uptime_record_${data.serviceId}_${Date.now()}` // Unique key for this request
$autoCancel: false,
$cancelKey: `uptime_record_${data.serviceId}_${Date.now()}`
};
// Store uptime history in the uptime_data collection
// Format data for PocketBase (use snake_case)
const record = await pb.collection('uptime_data').create({
service_id: data.serviceId,
timestamp: data.timestamp,
@@ -32,8 +27,9 @@ export const uptimeService = {
response_time: data.responseTime
}, options);
// Invalidate cache for this service after recording new data
uptimeCache.delete(`uptime_${data.serviceId}`);
// Invalidate cache for this service
const keysToDelete = Array.from(uptimeCache.keys()).filter(key => key.includes(`uptime_${data.serviceId}`));
keysToDelete.forEach(key => uptimeCache.delete(key));
console.log(`Uptime data recorded successfully with ID: ${record.id}`);
} catch (error) {
@@ -49,10 +45,9 @@ export const uptimeService = {
endDate?: Date
): Promise<UptimeData[]> {
try {
// Create cache key based on parameters
const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}`;
// Check if we have a valid cached result
// Check cache
const cached = uptimeCache.get(cacheKey);
if (cached && (Date.now() - cached.timestamp) < cached.expiresIn) {
console.log(`Using cached uptime history for service ${serviceId}`);
@@ -61,80 +56,74 @@ export const uptimeService = {
console.log(`Fetching uptime history for service ${serviceId}, limit: ${limit}`);
// Base filter for a specific service
let filter = `service_id='${serviceId}'`;
// Add date range filtering if provided
if (startDate && endDate) {
// Convert to ISO strings for PocketBase filtering
const startISO = startDate.toISOString();
const endISO = endDate.toISOString();
// Convert dates to UTC strings in the format PocketBase expects
const startUTC = startDate.toISOString();
const endUTC = endDate.toISOString();
// Log the date range we're filtering by
console.log(`Date range filter: ${startISO} to ${endISO}`);
console.log(`Date filter: ${startUTC} to ${endUTC}`);
filter += ` && timestamp >= '${startISO}' && timestamp <= '${endISO}'`;
// Use proper PocketBase date filtering syntax
filter += ` && timestamp >= "${startUTC}" && timestamp <= "${endUTC}"`;
}
// Calculate time difference to determine if it's a short range (like 60min)
const isShortTimeRange = startDate && endDate &&
(endDate.getTime() - startDate.getTime() <= 60 * 60 * 1000);
// For very short time ranges, adjust sorting and limit
const sort = '-timestamp'; // Default: newest first
const actualLimit = isShortTimeRange ? Math.max(limit, 300) : limit; // Ensure adequate points for short ranges
// Create custom request options to disable auto-cancellation
const options = {
filter: filter,
sort: sort,
$autoCancel: false, // Disable auto-cancellation for this request
$cancelKey: `uptime_history_${serviceId}_${Date.now()}` // Unique key for this request
sort: '-timestamp',
$autoCancel: false,
$cancelKey: `uptime_history_${serviceId}_${Date.now()}`
};
try {
// Get uptime history for a specific service with date filtering
const response = await pb.collection('uptime_data').getList(1, actualLimit, options);
console.log(`Filter query: ${filter}`);
const response = await pb.collection('uptime_data').getList(1, limit, options);
console.log(`Fetched ${response.items.length} uptime records for service ${serviceId}`);
if (response.items.length > 0) {
console.log(`Date range in results: ${response.items[response.items.length - 1].timestamp} to ${response.items[0].timestamp}`);
} else {
console.log(`No records found for filter: ${filter}`);
console.log(`Fetched ${response.items.length} uptime records for service ${serviceId}`);
// Map and return the data
const uptimeData = response.items.map(item => ({
id: item.id,
serviceId: item.service_id,
timestamp: item.timestamp,
status: item.status,
responseTime: item.response_time || 0,
date: item.timestamp, // Mapping timestamp to date
uptime: 100 // Default value for uptime
}));
// For short time ranges with few data points, we might need to ensure we have enough points
const shouldAddPlaceholderData = isShortTimeRange && uptimeData.length <= 2;
let finalData = uptimeData;
if (shouldAddPlaceholderData && uptimeData.length > 0) {
// We'll add some additional data points to ensure graph is visible
console.log("Adding placeholder data points to ensure graph visibility");
finalData = [...uptimeData];
}
// Cache the result
uptimeCache.set(cacheKey, {
data: finalData,
timestamp: Date.now(),
expiresIn: CACHE_TTL
// Try a fallback query without date filter to see if there's any data at all
const fallbackResponse = await pb.collection('uptime_data').getList(1, 10, {
filter: `service_id='${serviceId}'`,
sort: '-timestamp',
$autoCancel: false
});
return finalData;
} catch (err) {
throw err;
console.log(`Fallback query found ${fallbackResponse.items.length} total records for service`);
if (fallbackResponse.items.length > 0) {
console.log(`Latest record timestamp: ${fallbackResponse.items[0].timestamp}`);
console.log(`Oldest record timestamp: ${fallbackResponse.items[fallbackResponse.items.length - 1].timestamp}`);
}
}
const uptimeData = response.items.map(item => ({
id: item.id,
serviceId: item.service_id,
timestamp: item.timestamp,
status: item.status,
responseTime: item.response_time || 0,
date: item.timestamp,
uptime: 100
}));
// Cache the result
uptimeCache.set(cacheKey, {
data: uptimeData,
timestamp: Date.now(),
expiresIn: CACHE_TTL
});
return uptimeData;
} catch (error) {
console.error("Error fetching uptime history:", error);
// Try to return cached data even if it's expired, as a fallback
// Try to return cached data as fallback
const cacheKey = `uptime_${serviceId}_${limit}_${startDate?.toISOString() || ''}_${endDate?.toISOString() || ''}`;
const cached = uptimeCache.get(cacheKey);
if (cached) {
@@ -145,4 +134,4 @@ export const uptimeService = {
throw new Error('Failed to load uptime history.');
}
}
};
};