Skip to content
quarry Artifact [8f8d292fef]
Login

Artifact [8f8d292fef]

Artifact 8f8d292fef105a22161c2a1c9d2e3db41ea240ffecb2422973ec1791cf3e6055:


package obs

import (
	"context"
	"strconv"
	"sync/atomic"
)

type ctxRequest struct{}

var requestSeq atomic.Uint64

// WithRequest tags a context with a fresh request id and returns both.
//
// The id is what lets a store call name the page that caused it. Before
// it, the subprocess panel and the render panel were two independent
// lists: "GET /search took 1132ms" and "zit artifact ran 499 times"
// could not be connected even when one caused the other, so the page
// could find a slow route and never say why.
//
// A counter rather than a UUID: this identifies a request WITHIN one
// process's memory for as long as the rings hold it, and nothing
// compares ids across processes. A cheap monotonic value is the whole
// requirement.
func WithRequest(ctx context.Context) (context.Context, string) {
	id := strconv.FormatUint(requestSeq.Add(1), 36)
	return context.WithValue(ctx, ctxRequest{}, id), id
}

// RequestID is the tag on this context, empty when there is none —
// which is the ordinary case for work with no request behind it: ingest
// rounds, warm passes, the doc indexer. Callers record the empty string
// rather than guessing, because "background" is a true answer and a
// wrong attribution is not.
func RequestID(ctx context.Context) string {
	if ctx == nil {
		return ""
	}
	id, _ := ctx.Value(ctxRequest{}).(string)
	return id
}