@@ -80,7 +80,9 @@ will not be reflected in the served content.
80
80
81
81
func (s * serve ) run (ctx context.Context ) error {
82
82
p := newProfilerInterface (s .pprofAddr , s .logger )
83
- p .startEndpoint ()
83
+ if err := p .startEndpoint (); err != nil {
84
+ return fmt .Errorf ("could not start pprof endpoint: %v" , err )
85
+ }
84
86
if err := p .startCpuProfileCache (); err != nil {
85
87
return fmt .Errorf ("could not start CPU profile: %v" , err )
86
88
}
@@ -115,7 +117,7 @@ func (s *serve) run(ctx context.Context) error {
115
117
116
118
lis , err := net .Listen ("tcp" , ":" + s .port )
117
119
if err != nil {
118
- s . logger . Fatalf ("failed to listen: %s" , err )
120
+ return fmt . Errorf ("failed to listen: %s" , err )
119
121
}
120
122
121
123
grpcServer := grpc .NewServer ()
@@ -129,7 +131,9 @@ func (s *serve) run(ctx context.Context) error {
129
131
return grpcServer .Serve (lis )
130
132
}, func () {
131
133
grpcServer .GracefulStop ()
132
- p .stopEndpoint (p .logger .Context )
134
+ if err := p .stopEndpoint (ctx ); err != nil {
135
+ s .logger .Warnf ("error shutting down pprof server: %v" , err )
136
+ }
133
137
})
134
138
135
139
}
@@ -147,7 +151,8 @@ type profilerInterface struct {
147
151
cacheReady bool
148
152
cacheLock sync.RWMutex
149
153
150
- logger * logrus.Entry
154
+ logger * logrus.Entry
155
+ closeErr chan error
151
156
}
152
157
153
158
func newProfilerInterface (a string , log * logrus.Entry ) * profilerInterface {
@@ -162,10 +167,10 @@ func (p *profilerInterface) isEnabled() bool {
162
167
return p .addr != ""
163
168
}
164
169
165
- func (p * profilerInterface ) startEndpoint () {
170
+ func (p * profilerInterface ) startEndpoint () error {
166
171
// short-circuit if not enabled
167
172
if ! p .isEnabled () {
168
- return
173
+ return nil
169
174
}
170
175
171
176
mux := http .NewServeMux ()
@@ -181,14 +186,22 @@ func (p *profilerInterface) startEndpoint() {
181
186
Handler : mux ,
182
187
}
183
188
184
- // goroutine exits with main
185
- go func () {
189
+ lis , err := net .Listen ("tcp" , p .addr )
190
+ if err != nil {
191
+ return err
192
+ }
186
193
187
- p .logger .Info ("starting pprof endpoint" )
188
- if err := p .server .ListenAndServe (); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
189
- p .logger .Fatal (err )
190
- }
194
+ p .closeErr = make (chan error )
195
+ go func () {
196
+ p .closeErr <- func () error {
197
+ p .logger .Info ("starting pprof endpoint" )
198
+ if err := p .server .Serve (lis ); err != nil && ! errors .Is (err , http .ErrServerClosed ) {
199
+ return err
200
+ }
201
+ return nil
202
+ }()
191
203
}()
204
+ return nil
192
205
}
193
206
194
207
func (p * profilerInterface ) startCpuProfileCache () error {
@@ -222,10 +235,14 @@ func (p *profilerInterface) httpHandler(w http.ResponseWriter, r *http.Request)
222
235
w .Write (p .cache .Bytes ())
223
236
}
224
237
225
- func (p * profilerInterface ) stopEndpoint (ctx context.Context ) {
238
+ func (p * profilerInterface ) stopEndpoint (ctx context.Context ) error {
239
+ if ! p .isEnabled () {
240
+ return nil
241
+ }
226
242
if err := p .server .Shutdown (ctx ); err != nil {
227
- p . logger . Fatal ( err )
243
+ return err
228
244
}
245
+ return <- p .closeErr
229
246
}
230
247
231
248
func (p * profilerInterface ) isCacheReady () bool {
0 commit comments