@@ -98,27 +98,54 @@ func (a *WFAlerts) Merge(results ...*WFAlerts) {
9898 a .Data .Alerts = alerts
9999}
100100
101- // MergeAndWriteAlerts merges the provided Responses into a single prometheus Alerts data object,
102- // and writes it to the provided ResponseWriter
103- func MergeAndWriteAlerts (w http.ResponseWriter , r * http.Request , rgs merge.ResponseGates ) {
104- var a * WFAlerts
101+ // Mergeable represents types that can merge with other instances of the same type
102+ type Mergeable [T any ] interface {
103+ * T
104+ Merge (... * T )
105+ }
106+
107+ // MarshallerPtr represents pointer types that can start marshaling with an envelope
108+ type MarshallerPtr [T any ] interface {
109+ * T
110+ StartMarshal (w io.Writer , httpStatus int )
111+ }
112+
113+ // unmarshalAndMerge is a generic function that handles the common pattern of
114+ // unmarshaling JSON responses and merging them using a Merge method
115+ func unmarshalAndMerge [T any , PT Mergeable [T ]](
116+ r * http.Request ,
117+ rgs merge.ResponseGates ,
118+ errorType string ,
119+ newInstance func () PT ,
120+ ) (PT , []int , * http.Response ) {
121+ var result PT
105122 responses , bestResp := gatherResponses (r , rgs , func (rg * merge.ResponseGate ) bool {
106- a1 := & WFAlerts {}
107- err := json .Unmarshal (rg .Body (), & a1 )
123+ instance := newInstance ()
124+ err := json .Unmarshal (rg .Body (), instance )
108125 if err != nil {
109- logger .Error ("alerts unmarshaling error" ,
126+ logger .Error (errorType + " unmarshaling error" ,
110127 logging.Pairs {"provider" : providers .Prometheus , "detail" : err .Error ()})
111128 return false
112129 }
113- if a == nil {
114- a = a1
130+ if result == nil {
131+ result = instance
115132 } else {
116- a .Merge (a1 )
133+ result .Merge (instance )
117134 }
118135 return true
119136 })
137+ return result , responses , bestResp
138+ }
120139
121- if a == nil || len (responses ) == 0 {
140+ // handleMergeResult handles the common error pattern and starts marshaling if successful
141+ func handleMergeResult [T any , PT MarshallerPtr [T ]](
142+ w http.ResponseWriter ,
143+ r * http.Request ,
144+ result PT ,
145+ responses []int ,
146+ bestResp * http.Response ,
147+ ) bool {
148+ if result == nil || len (responses ) == 0 {
122149 if bestResp != nil {
123150 h := w .Header ()
124151 headers .Merge (h , bestResp .Header )
@@ -127,12 +154,25 @@ func MergeAndWriteAlerts(w http.ResponseWriter, r *http.Request, rgs merge.Respo
127154 } else {
128155 failures .HandleBadGateway (w , r )
129156 }
130- return
157+ return false
131158 }
132159
133160 sort .Ints (responses )
134161 statusCode := responses [0 ]
135- a .StartMarshal (w , statusCode )
162+ result .StartMarshal (w , statusCode )
163+ return true
164+ }
165+
166+ // MergeAndWriteAlerts merges the provided Responses into a single prometheus Alerts data object,
167+ // and writes it to the provided ResponseWriter
168+ func MergeAndWriteAlerts (w http.ResponseWriter , r * http.Request , rgs merge.ResponseGates ) {
169+ a , responses , bestResp := unmarshalAndMerge (r , rgs , "alerts" , func () * WFAlerts {
170+ return & WFAlerts {}
171+ })
172+
173+ if ! handleMergeResult (w , r , a , responses , bestResp ) {
174+ return
175+ }
136176
137177 var sep string
138178 w .Write ([]byte (`,"data":{"alerts":[` ))
0 commit comments