From 54c741b56aa020f5e23d5334a7dbecccf63aef36 Mon Sep 17 00:00:00 2001 From: hhftechnologies Date: Fri, 23 Jan 2026 11:52:06 +0530 Subject: [PATCH 1/7] service-bug-ui --- services/resource_watcher.go | 45 +++++++++-- services/service_watcher.go | 23 +++--- .../components/resources/ResourceDetail.tsx | 79 +++++++++++++------ 3 files changed, 107 insertions(+), 40 deletions(-) diff --git a/services/resource_watcher.go b/services/resource_watcher.go index efe53c749..382281912 100644 --- a/services/resource_watcher.go +++ b/services/resource_watcher.go @@ -119,7 +119,6 @@ func (rw *ResourceWatcher) Stop() { // checkResources fetches resources from the configured data source and updates the database func (rw *ResourceWatcher) checkResources() error { - log.Println("Checking for resources using configured data source...") // Create a context with timeout for the operation ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -219,8 +218,7 @@ func (rw *ResourceWatcher) updateOrCreateResource(resource models.Resource) (str `, pangolinRouterID).Scan(&internalID, &status) if err == nil { - // Found by pangolin_router_id - update it - log.Printf("Found resource by pangolin_router_id %s (internal: %s)", pangolinRouterID, internalID) + // Found by pangolin_router_id - update it (only if changed) if err := rw.updateExistingResourceByInternalID(internalID, pangolinRouterID, resource); err != nil { return "", err } @@ -234,9 +232,7 @@ func (rw *ResourceWatcher) updateOrCreateResource(resource models.Resource) (str `, resource.Host).Scan(&internalID, &status) if err == nil { - // Found by host - Pangolin changed the router ID, just update pangolin_router_id - log.Printf("Found resource by host %s (internal: %s), updating pangolin_router_id from old to %s", - resource.Host, internalID, pangolinRouterID) + // Found by host - Pangolin changed the router ID, update pangolin_router_id (only if changed) if err := rw.updateExistingResourceByInternalID(internalID, pangolinRouterID, resource); err != nil { return "", err } @@ -250,8 +246,7 @@ func (rw *ResourceWatcher) updateOrCreateResource(resource models.Resource) (str `, pangolinRouterID, resource.Host).Scan(&internalID, &status) if err == nil { - // Found legacy resource - update it - log.Printf("Found legacy resource %s, updating", internalID) + // Found legacy resource - update it (only if changed) if err := rw.updateExistingResourceByInternalID(internalID, pangolinRouterID, resource); err != nil { return "", err } @@ -263,7 +258,41 @@ func (rw *ResourceWatcher) updateOrCreateResource(resource models.Resource) (str } // updateExistingResourceByInternalID updates an existing resource using its internal UUID +// Only performs update if the data has actually changed func (rw *ResourceWatcher) updateExistingResourceByInternalID(internalID, pangolinRouterID string, resource models.Resource) error { + // First, check if any data has actually changed + var existingPangolinRouterID, existingHost, existingServiceID, existingSourceType string + var existingRouterPriority int + var routerPriorityManual int + + err := rw.db.QueryRow(` + SELECT COALESCE(pangolin_router_id, ''), host, service_id, COALESCE(source_type, ''), + COALESCE(router_priority, 0), COALESCE(router_priority_manual, 0) + FROM resources WHERE id = ? + `, internalID).Scan(&existingPangolinRouterID, &existingHost, &existingServiceID, + &existingSourceType, &existingRouterPriority, &routerPriorityManual) + + if err != nil { + // If we can't read existing data, proceed with update + log.Printf("Warning: Could not read existing resource %s: %v - will update", internalID, err) + } else { + // Check if essential fields have changed + essentialFieldsChanged := existingPangolinRouterID != pangolinRouterID || + existingHost != resource.Host || + existingServiceID != resource.ServiceID || + existingSourceType != resource.SourceType + + // Check if router priority needs update (only if not manually overridden) + priorityNeedsUpdate := resource.RouterPriority > 0 && + routerPriorityManual == 0 && + existingRouterPriority != resource.RouterPriority + + // If nothing changed, skip the update entirely + if !essentialFieldsChanged && !priorityNeedsUpdate { + return nil + } + } + return rw.db.WithTransaction(func(tx *sql.Tx) error { log.Printf("Updating resource (internal: %s, pangolin: %s, host: %s)", internalID, pangolinRouterID, resource.Host) diff --git a/services/service_watcher.go b/services/service_watcher.go index b2f4b41ec..3e95ee9a7 100644 --- a/services/service_watcher.go +++ b/services/service_watcher.go @@ -111,7 +111,6 @@ func (sw *ServiceWatcher) Stop() { // checkServices fetches services from the configured data source and updates the database func (sw *ServiceWatcher) checkServices() error { - log.Println("Checking for services using configured data source...") // Create a context with timeout for the operation ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) @@ -215,10 +214,10 @@ func (sw *ServiceWatcher) updateOrCreateService(service models.Service) error { // Try checking if service exists with different provider suffixes var found bool err = sw.db.QueryRow( - "SELECT 1 FROM services WHERE id LIKE ?", + "SELECT 1 FROM services WHERE id LIKE ?", normalizedID+"%", ).Scan(&exists) - + if err == nil { // Found a service with this base name but different suffix found = true @@ -227,13 +226,18 @@ func (sw *ServiceWatcher) updateOrCreateService(service models.Service) error { "SELECT id FROM services WHERE id LIKE ? LIMIT 1", normalizedID+"%", ).Scan(&altID) - + if err == nil { - log.Printf("Found existing service with different suffix: %s - will update", altID) - return sw.updateService(service, altID) + // Check if update is actually needed before updating + if shouldUpdateService(sw.db, service, altID) { + log.Printf("Updating service with different suffix: %s", altID) + return sw.updateService(service, altID) + } + // Service exists and hasn't changed, skip update + return nil } } - + if !found { // Service doesn't exist with any suffix, create it service.ID = normalizedID @@ -515,9 +519,10 @@ func (sw *ServiceWatcher) updateService(service models.Service, existingID strin log.Printf("Error getting rows affected: %v", err) } else if rowsAffected == 0 { log.Printf("Warning: Update did not affect any rows for service %s", existingID) + } else { + log.Printf("Updated existing service: %s", existingID) } - - log.Printf("Updated existing service: %s", existingID) + return nil }) } diff --git a/ui/src/components/resources/ResourceDetail.tsx b/ui/src/components/resources/ResourceDetail.tsx index a539e2bb5..63e7ad089 100644 --- a/ui/src/components/resources/ResourceDetail.tsx +++ b/ui/src/components/resources/ResourceDetail.tsx @@ -572,30 +572,63 @@ export function ResourceDetail() { {selectedResource.service_id ? ( -
-
-

{selectedResource.service_id}

-

Currently assigned

-
-
- - + <> +
+
+

{selectedResource.service_id}

+

Currently assigned

+
+
+ + +
-
+ {/* Display server targets from the assigned service */} + {(() => { + const assignedService = services.find(s => s.id === selectedResource.service_id) + if (!assignedService) return null + + const config = assignedService.config as Record + const servers = config?.servers as Array<{ url?: string; address?: string; weight?: number }> | undefined + + if (!servers || servers.length === 0) return null + + return ( +
+ +
+ {servers.map((server, index) => ( +
+ {server.url || server.address || 'Unknown'} + {server.weight !== undefined && ( + + weight: {server.weight} + + )} +
+ ))} +
+
+ ) + })()} + ) : (