This commit is contained in:
@@ -59,6 +59,8 @@ func loadConfig() AppConfig {
|
||||
m.HelloInterval = parseDuration(os.Getenv("MESH_HELLO_INTERVAL"), 20*time.Second)
|
||||
m.HelloFanout = parseIntEnv(os.Getenv("MESH_HELLO_FANOUT"), 8)
|
||||
|
||||
m.BlobTimeout = parseDuration(os.Getenv("MESH_BLOB_TIMEOUT"), 0)
|
||||
|
||||
// Wenn keine AdvertURL gesetzt ist, versuche eine sinnvolle Herleitung:
|
||||
if strings.TrimSpace(m.AdvertURL) == "" {
|
||||
m.AdvertURL = inferAdvertURL(m.BindAddr)
|
||||
|
||||
@@ -41,6 +41,8 @@ type Config struct {
|
||||
// NEU:
|
||||
HelloInterval time.Duration // wie oft pingen
|
||||
HelloFanout int // wie viele Peers pro Tick
|
||||
|
||||
BlobTimeout time.Duration
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
@@ -714,31 +716,31 @@ func (n *Node) blobHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// sendBlobRequest schickt eine signierte Anfrage an /mesh/blob und liefert die Response
|
||||
// zurück (Caller MUSS resp.Body schließen!). Bei HTTP 200 wird der Peer als gesehen markiert.
|
||||
func (n *Node) sendBlobRequest(url, id string) (*http.Response, error) {
|
||||
body, _ := json.Marshal(struct {
|
||||
b, _ := json.Marshal(struct {
|
||||
ID string `json:"id"`
|
||||
}{ID: id})
|
||||
|
||||
req, _ := http.NewRequest(http.MethodPost, strings.TrimRight(url, "/")+"/mesh/blob", bytes.NewReader(body))
|
||||
req.Header.Set("X-Mesh-Sig", n.sign(body))
|
||||
req, _ := http.NewRequest(http.MethodPost, strings.TrimRight(url, "/")+"/mesh/blob", bytes.NewReader(b))
|
||||
req.Header.Set("X-Mesh-Sig", n.sign(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// kurzer Timeout für Blob-Requests (anpassbar)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
|
||||
defer cancel()
|
||||
// ❗ WICHTIG: kein kurzer Timeout. Optional: großer Timeout aus Config
|
||||
ctx := context.Background()
|
||||
if n.cfg.BlobTimeout > 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(context.Background(), n.cfg.BlobTimeout)
|
||||
defer cancel()
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
resp, err := n.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// OK → Peer als "gesehen" markieren und Response (für Streaming) zurückgeben
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
n.touchPeer(url)
|
||||
return resp, nil // Caller liest/streamt Body und schließt ihn
|
||||
n.touchPeer(url) // ausgehender Erfolg zählt als "gesehen"
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Nicht-OK → Body leeren/schließen und Fehler zurück
|
||||
io.Copy(io.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
return nil, fmt.Errorf("blob %s from %s: %s", id, url, resp.Status)
|
||||
|
||||
Reference in New Issue
Block a user