From 9152d7fb2f9a0b849056366a65c69f259dade36a Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 23 May 2026 09:13:42 +0200 Subject: [PATCH] chore(ur): move structs to reduce dependency chain lib/ur brings in a lot of dependencies we don't need in e.g. stcrashreceiver, who only needs the small failure reporting structs. Make those part of the lean `contract` package instead. Signed-off-by: Jakob Borg --- cmd/infra/stcrashreceiver/main.go | 6 ++--- lib/model/indexhandler.go | 4 ++-- lib/ur/contract/contract.go | 13 ++++++++++ lib/ur/failurereporting.go | 40 +++++++++++-------------------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/cmd/infra/stcrashreceiver/main.go b/cmd/infra/stcrashreceiver/main.go index c82d40ee9..54356f81f 100644 --- a/cmd/infra/stcrashreceiver/main.go +++ b/cmd/infra/stcrashreceiver/main.go @@ -30,7 +30,7 @@ import ( raven "github.com/getsentry/raven-go" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/syncthing/syncthing/lib/build" - "github.com/syncthing/syncthing/lib/ur" + "github.com/syncthing/syncthing/lib/ur/contract" ) const maxRequestSize = 1 << 20 // 1 MiB @@ -131,7 +131,7 @@ func handleFailureFn(dsn, failureDir string, ignore *ignorePatterns) func(w http return } - var reports []ur.FailureReport + var reports []contract.FailureReport err = json.Unmarshal(bs, &reports) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) @@ -179,7 +179,7 @@ func handleFailureFn(dsn, failureDir string, ignore *ignorePatterns) func(w http } } -func saveFailureWithGoroutines(data ur.FailureData, failureDir string) (string, error) { +func saveFailureWithGoroutines(data contract.FailureData, failureDir string) (string, error) { bs := make([]byte, len(data.Description)+len(data.Goroutines)) copy(bs, data.Description) copy(bs[len(data.Description):], data.Goroutines) diff --git a/lib/model/indexhandler.go b/lib/model/indexhandler.go index 5cf73ab3e..c1c03cec8 100644 --- a/lib/model/indexhandler.go +++ b/lib/model/indexhandler.go @@ -20,7 +20,7 @@ import ( "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/svcutil" - "github.com/syncthing/syncthing/lib/ur" + "github.com/syncthing/syncthing/lib/ur/contract" ) type indexHandler struct { @@ -470,7 +470,7 @@ func (s *indexHandler) logSequenceAnomaly(msg string, extra map[string]any) { extraStrs[k] = fmt.Sprint(v) } - s.evLogger.Log(events.Failure, ur.FailureData{ + s.evLogger.Log(events.Failure, contract.FailureData{ Description: msg, Extra: extraStrs, }) diff --git a/lib/ur/contract/contract.go b/lib/ur/contract/contract.go index 1ea77fe7e..15b52420c 100644 --- a/lib/ur/contract/contract.go +++ b/lib/ur/contract/contract.go @@ -282,3 +282,16 @@ func clear(v interface{}, since int) error { } return nil } + +type FailureReport struct { + FailureData + + Count int + Version string +} + +type FailureData struct { + Description string + Goroutines string + Extra map[string]string +} diff --git a/lib/ur/failurereporting.go b/lib/ur/failurereporting.go index 8d0626b2d..bbf2c53ec 100644 --- a/lib/ur/failurereporting.go +++ b/lib/ur/failurereporting.go @@ -23,6 +23,7 @@ import ( "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/svcutil" "github.com/syncthing/syncthing/lib/tlsutil" + "github.com/syncthing/syncthing/lib/ur/contract" "github.com/thejerf/suture/v4" ) @@ -39,23 +40,10 @@ var ( invalidEventDataType = "failure event data is not a string" ) -type FailureReport struct { - FailureData - - Count int - Version string -} - -type FailureData struct { - Description string - Goroutines string - Extra map[string]string -} - -func FailureDataWithGoroutines(description string) FailureData { +func FailureDataWithGoroutines(description string) contract.FailureData { var buf strings.Builder pprof.Lookup("goroutine").WriteTo(&buf, 1) - return FailureData{ + return contract.FailureData{ Description: description, Goroutines: buf.String(), Extra: make(map[string]string), @@ -86,7 +74,7 @@ type failureHandler struct { type failureStat struct { first, last time.Time count int - data FailureData + data contract.FailureData } func (h *failureHandler) Serve(ctx context.Context) error { @@ -105,24 +93,24 @@ func (h *failureHandler) Serve(ctx context.Context) error { if !ok { // Just to be safe - shouldn't ever happen, as // evChan is set to nil when unsubscribing. - h.addReport(FailureData{Description: evChanClosed}, time.Now()) + h.addReport(contract.FailureData{Description: evChanClosed}, time.Now()) evChan = nil continue } - var data FailureData + var data contract.FailureData switch d := e.Data.(type) { case string: data.Description = d - case FailureData: + case contract.FailureData: data = d default: // Same here, shouldn't ever happen. - h.addReport(FailureData{Description: invalidEventDataType}, time.Now()) + h.addReport(contract.FailureData{Description: invalidEventDataType}, time.Now()) continue } h.addReport(data, e.Time) case <-timer.C: - reports := make([]FailureReport, 0, len(h.buf)) + reports := make([]contract.FailureReport, 0, len(h.buf)) now := time.Now() for descr, stat := range h.buf { if now.Sub(stat.last) > minDelay || now.Sub(stat.first) > maxDelay { @@ -152,7 +140,7 @@ func (h *failureHandler) Serve(ctx context.Context) error { if sub != nil { sub.Unsubscribe() if len(h.buf) > 0 { - reports := make([]FailureReport, 0, len(h.buf)) + reports := make([]contract.FailureReport, 0, len(h.buf)) for _, stat := range h.buf { reports = append(reports, newFailureReport(stat)) } @@ -179,7 +167,7 @@ func (h *failureHandler) applyOpts(opts config.OptionsConfiguration, sub events. return url, nil, nil } -func (h *failureHandler) addReport(data FailureData, evTime time.Time) { +func (h *failureHandler) addReport(data contract.FailureData, evTime time.Time) { if stat, ok := h.buf[data.Description]; ok { stat.last = evTime stat.count++ @@ -204,7 +192,7 @@ func (*failureHandler) String() string { return "FailureHandler" } -func sendFailureReports(ctx context.Context, reports []FailureReport, url string) { +func sendFailureReports(ctx context.Context, reports []contract.FailureReport, url string) { var b bytes.Buffer if err := json.NewEncoder(&b).Encode(reports); err != nil { panic(err) @@ -235,8 +223,8 @@ func sendFailureReports(ctx context.Context, reports []FailureReport, url string resp.Body.Close() } -func newFailureReport(stat *failureStat) FailureReport { - return FailureReport{ +func newFailureReport(stat *failureStat) contract.FailureReport { + return contract.FailureReport{ FailureData: stat.data, Count: stat.count, Version: build.LongVersion,