package main import ( "encoding/json" "fmt" "time" ) var imageResultsChan = make(chan []ImageSearchResult) func handleImageResultsMessage(msg Message) { var results []ImageSearchResult err := json.Unmarshal([]byte(msg.Content), &results) if err != nil { printWarn("Error unmarshalling image results: %v", err) return } printDebug("Received image results: %+v", results) // Send results to imageResultsChan go func() { imageResultsChan <- results }() } func sendImageSearchRequestToNode(nodeAddr, query, safe, lang string, page int, visitedNodes []string) ([]ImageSearchResult, error) { visitedNodes = append(visitedNodes, nodeAddr) searchParams := struct { Query string `json:"query"` Safe string `json:"safe"` Lang string `json:"lang"` Page int `json:"page"` ResponseAddr string `json:"responseAddr"` VisitedNodes []string `json:"visitedNodes"` }{ Query: query, Safe: safe, Lang: lang, Page: page, ResponseAddr: fmt.Sprintf("http://localhost:%d/node", config.Port), VisitedNodes: visitedNodes, } msgBytes, err := json.Marshal(searchParams) if err != nil { return nil, fmt.Errorf("failed to marshal search parameters: %v", err) } msg := Message{ ID: hostID, Type: "search-image", Content: string(msgBytes), } err = sendMessage(nodeAddr, msg) if err != nil { return nil, fmt.Errorf("failed to send search request to node %s: %v", nodeAddr, err) } // Wait for results select { case res := <-imageResultsChan: return res, nil case <-time.After(30 * time.Second): return nil, fmt.Errorf("timeout waiting for results from node %s", nodeAddr) } } func tryOtherNodesForImageSearch(query, safe, lang string, page int, visitedNodes []string) []ImageSearchResult { for _, nodeAddr := range peers { if contains(visitedNodes, nodeAddr) { continue // Skip nodes already visited } results, err := sendImageSearchRequestToNode(nodeAddr, query, safe, lang, page, visitedNodes) if err != nil { printWarn("Error contacting node %s: %v", nodeAddr, err) continue } if len(results) > 0 { return results } } return nil }