Skip to content

Commit dc93264

Browse files
committed
Add pprof server on 6060 and /debug route
1 parent 540f5b3 commit dc93264

3 files changed

Lines changed: 66 additions & 6 deletions

File tree

internal/dnfjson/cache.go

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package dnfjson
22

33
import (
4+
"bytes"
5+
"encoding/gob"
46
"fmt"
57
"io/fs"
68
"os"
@@ -213,8 +215,8 @@ func dirSize(path string) (uint64, error) {
213215
// dnfResults holds the results of a dnfjson request
214216
// expire is the time the request was made, used to expire the entry
215217
type dnfResults struct {
216-
expire time.Time
217-
pkgs rpmmd.PackageList
218+
Expire time.Time
219+
Pkgs rpmmd.PackageList
218220
}
219221

220222
// dnfCache is a cache of results from dnf-json requests
@@ -241,7 +243,7 @@ func (d *dnfCache) CleanCache() {
241243

242244
// Delete expired resultCache entries
243245
for k := range d.results {
244-
if time.Since(d.results[k].expire) > d.timeout {
246+
if time.Since(d.results[k].Expire) > d.timeout {
245247
delete(d.results, k)
246248
}
247249
}
@@ -254,15 +256,32 @@ func (d *dnfCache) Get(hash string) (rpmmd.PackageList, bool) {
254256
defer d.RUnlock()
255257

256258
result, ok := d.results[hash]
257-
if !ok || time.Since(result.expire) >= d.timeout {
259+
if !ok || time.Since(result.Expire) >= d.timeout {
258260
return rpmmd.PackageList{}, false
259261
}
260-
return result.pkgs, true
262+
return result.Pkgs, true
261263
}
262264

263265
// Store saves the package list in the cache
264266
func (d *dnfCache) Store(hash string, pkgs rpmmd.PackageList) {
265267
d.Lock()
266268
defer d.Unlock()
267-
d.results[hash] = dnfResults{expire: time.Now(), pkgs: pkgs}
269+
d.results[hash] = dnfResults{Expire: time.Now(), Pkgs: pkgs}
270+
}
271+
272+
// Info returns about about the cache
273+
func (d *dnfCache) Info() map[string]string {
274+
275+
m := make(map[string]string)
276+
m["timeout"] = fmt.Sprintf("%d", d.timeout)
277+
m["entries"] = fmt.Sprintf("%d", len(d.results))
278+
279+
// Try to guesstimate the amount of memory used by marshaling the cache into a byte stream
280+
b := new(bytes.Buffer)
281+
if err := gob.NewEncoder(b).Encode(d.results); err != nil {
282+
m["error"] = err.Error()
283+
} else {
284+
m["size"] = fmt.Sprintf("%d", b.Len())
285+
}
286+
return m
268287
}

internal/dnfjson/dnfjson.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ func NewSolver(modulePlatformID string, releaseVer string, arch string, cacheDir
111111
return s.NewWithConfig(modulePlatformID, releaseVer, arch)
112112
}
113113

114+
func (s *Solver) CacheDebugInfo() map[string]string {
115+
return s.BaseSolver.resultCache.Info()
116+
}
117+
114118
// Depsolve the list of required package sets with explicit excludes using
115119
// their associated repositories. Each package set is depsolved as a separate
116120
// transactions in a chain. It returns a list of all packages (with solved

internal/weldr/api.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"strings"
2626
"time"
2727

28+
_ "net/http/pprof" //nolint:gosec
29+
2830
"github.com/BurntSushi/toml"
2931
"github.com/gobwas/glob"
3032
"github.com/google/uuid"
@@ -201,6 +203,12 @@ func New(repoPaths []string, stateDir string, solver *dnfjson.BaseSolver, dr *di
201203
distros: validDistros(rr, dr, archName, logger),
202204
distrosImageTypeDenylist: distrosImageTypeDenylist,
203205
}
206+
207+
// XXX BCL
208+
go func() {
209+
log.Println(http.ListenAndServe("localhost:6060", nil))
210+
}()
211+
204212
return setupRouter(api), nil
205213
}
206214

@@ -212,6 +220,7 @@ func setupRouter(api *API) *API {
212220
api.router.NotFound = http.HandlerFunc(notFoundHandler)
213221

214222
api.router.GET("/api/status", api.statusHandler)
223+
api.router.GET("/api/debug", api.debugHandler)
215224
api.router.GET("/api/v:version/projects/source/list", api.sourceListHandler)
216225
api.router.GET("/api/v:version/projects/source/info/", api.sourceEmptyInfoHandler)
217226
api.router.GET("/api/v:version/projects/source/info/:sources", api.sourceInfoHandler)
@@ -611,6 +620,34 @@ func (api *API) statusHandler(writer http.ResponseWriter, request *http.Request,
611620
common.PanicOnError(err)
612621
}
613622

623+
func (api *API) debugHandler(writer http.ResponseWriter, request *http.Request, _ httprouter.Params) {
624+
625+
distroName, err := api.parseDistro(request.URL.Query())
626+
if err != nil {
627+
errors := responseError{
628+
ID: "DistroError",
629+
Msg: err.Error(),
630+
}
631+
statusResponseError(writer, http.StatusBadRequest, errors)
632+
return
633+
}
634+
635+
d := api.getDistro(distroName)
636+
if d == nil {
637+
errors := responseError{
638+
ID: "DistroError",
639+
Msg: fmt.Sprintf("GetDistro - unknown distribution: %s", distroName),
640+
}
641+
statusResponseError(writer, http.StatusBadRequest, errors)
642+
return
643+
}
644+
645+
solver := api.solver.NewWithConfig(d.ModulePlatformID(), d.Releasever(), api.archName)
646+
info := solver.CacheDebugInfo()
647+
err = json.NewEncoder(writer).Encode(info)
648+
common.PanicOnError(err)
649+
}
650+
614651
func (api *API) sourceListHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
615652
if !verifyRequestVersion(writer, params, 0) {
616653
return

0 commit comments

Comments
 (0)