Skip to content
edgesync Artifact [d3d47d118f]
Login

Artifact [d3d47d118f]

Artifact d3d47d118f63ce65201b44c9df298436fddc417d8eeb73d94730c2e78ace6359:


package agent

import (
	"context"
	"log/slog"

	libfossil "github.com/danmestas/libfossil"
)

// syncOutcome carries the result of a single per-target sync attempt
// inside one poll cycle. Either result or err is set (never both).
type syncOutcome struct {
	target syncTarget
	result *libfossil.SyncResult
	err    error
}

// emitSyncOutcomes logs the per-target outcomes from one poll cycle
// and invokes PostSyncHook on every successful outcome.
//
// Failed outcomes log at ERROR when no target in this cycle succeeded
// (sync as a whole failed; operator action likely needed). When at
// least one target succeeded, failed outcomes log at DEBUG instead —
// sync as a whole succeeded, isolated transport-level noise (e.g.
// the round-0 NATS subject-interest race) shouldn't trip alerting.
//
// The legacy `a.logf("sync error [%s]: %v", ...)` callback fires
// regardless of slog level so harness-supplied loggers stay
// informed without slog depending on them.
func (a *Agent) emitSyncOutcomes(ctx context.Context, outcomes []syncOutcome) {
	anySuccess := false
	for _, o := range outcomes {
		if o.err == nil {
			anySuccess = true
			break
		}
	}
	failedLevel := slog.LevelError
	if anySuccess {
		failedLevel = slog.LevelDebug
	}

	for _, o := range outcomes {
		if o.err != nil {
			a.logf("sync error [%s]: %v", o.target.label, o.err)
			slog.LogAttrs(ctx, failedLevel, "sync error",
				slog.String("target", o.target.label),
				slog.Any("error", o.err),
			)
			continue
		}
		a.logf("sync done [%s]: ↑%d ↓%d rounds=%d",
			o.target.label, o.result.FilesSent, o.result.FilesRecvd, o.result.Rounds)
		slog.DebugContext(ctx, "sync details",
			"target", o.target.label,
			"rounds", o.result.Rounds,
			"files_sent", o.result.FilesSent,
			"files_recv", o.result.FilesRecvd,
			"bytes_sent", o.result.BytesSent,
			"bytes_recv", o.result.BytesRecvd,
			"uv_sent", o.result.UVFilesSent,
			"uv_recv", o.result.UVFilesRecvd,
			"errors", len(o.result.Errors),
		)
		for _, e := range o.result.Errors {
			a.logf("sync warning [%s]: %s", o.target.label, e)
		}
		if a.config.PostSyncHook != nil {
			a.config.PostSyncHook(o.result)
		}
	}
}