@@ -5,7 +5,9 @@ package middleware
5
5
import (
6
6
"context"
7
7
"fmt"
8
+ "maps"
8
9
"net/http"
10
+ "slices"
9
11
"strconv"
10
12
"strings"
11
13
"sync"
@@ -14,9 +16,6 @@ import (
14
16
"github.com/pace/bricks/maintenance/log"
15
17
)
16
18
17
- // depFormat is the format of a single dependency report
18
- const depFormat = "%s:%d"
19
-
20
19
// ExternalDependencyHeaderName name of the HTTP header that is used for reporting
21
20
const ExternalDependencyHeaderName = "External-Dependencies"
22
21
@@ -85,30 +84,29 @@ func ExternalDependencyContextFromContext(ctx context.Context) *ExternalDependen
85
84
// during the request livecycle
86
85
type ExternalDependencyContext struct {
87
86
mu sync.RWMutex
88
- dependencies [] externalDependency
87
+ dependencies map [ string ]time. Duration
89
88
}
90
89
91
90
func (c * ExternalDependencyContext ) AddDependency (name string , duration time.Duration ) {
92
91
c .mu .Lock ()
93
- c .dependencies = append (c .dependencies , externalDependency {
94
- Name : name ,
95
- Duration : duration ,
96
- })
97
- c .mu .Unlock ()
92
+ defer c .mu .Unlock ()
93
+
94
+ if c .dependencies == nil {
95
+ c .dependencies = make (map [string ]time.Duration )
96
+ }
97
+
98
+ c .dependencies [name ] += duration
98
99
}
99
100
100
- // String formats all external dependencies
101
+ // String formats all external dependencies. The format is "name:duration[,name:duration]..." and sorted by name.
101
102
func (c * ExternalDependencyContext ) String () string {
102
103
var b strings.Builder
103
- sep := len (c .dependencies ) - 1
104
- for _ , dep := range c .dependencies {
105
- b .WriteString (dep .String ())
106
- if sep > 0 {
107
- b .WriteByte (',' )
108
- sep --
109
- }
104
+
105
+ for _ , key := range slices .Sorted (maps .Keys (c .dependencies )) {
106
+ b .WriteString (fmt .Sprintf ("%s:%d," , key , c .dependencies [key ].Milliseconds ()))
110
107
}
111
- return b .String ()
108
+
109
+ return strings .TrimRight (b .String (), "," )
112
110
}
113
111
114
112
// Parse a external dependency value
@@ -127,15 +125,3 @@ func (c *ExternalDependencyContext) Parse(s string) {
127
125
c .AddDependency (value [:index ], time .Millisecond * time .Duration (dur ))
128
126
}
129
127
}
130
-
131
- // externalDependency represents one external dependency that
132
- // was involved in the process to creating a response
133
- type externalDependency struct {
134
- Name string // canonical name of the source
135
- Duration time.Duration // time spend with the external dependency
136
- }
137
-
138
- // String returns a formated single external dependency
139
- func (r externalDependency ) String () string {
140
- return fmt .Sprintf (depFormat , r .Name , r .Duration .Milliseconds ())
141
- }
0 commit comments