Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit f517373

Browse files
authored
tenant: pprof for missing tenant in FromContext (#64405)
Instead of adding instrumentation for each place we expect a tenant, we instead assume that we always expect a tenant if FromContext is called. This should allow us to not miss any places. Note: this does remove the logging we had in diskcache, but it seems more reasonable to just use pprof for something that can be noisy? Test Plan: just gonna rely on CI since this defaults to off.
1 parent e65e736 commit f517373

File tree

6 files changed

+19
-57
lines changed

6 files changed

+19
-57
lines changed

internal/database/dbconn/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@ go_library(
1515
"metrics.go",
1616
"open.go",
1717
"postgres_version.go",
18-
"tenant_pprof.go",
1918
],
2019
importpath = "github.com/sourcegraph/sourcegraph/internal/database/dbconn",
2120
visibility = ["//:__subpackages__"],
2221
deps = [
2322
"//internal/database/dbconn/rds",
2423
"//internal/env",
2524
"//internal/lazyregexp",
26-
"//internal/tenant",
2725
"//lib/errors",
2826
"//lib/output",
2927
"@com_github_jackc_pgx_v4//:pgx",

internal/database/dbconn/open.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,11 @@ func (n *extendedConn) CheckNamedValue(namedValue *driver.NamedValue) error {
220220
}
221221

222222
func (n *extendedConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
223-
pprofCheckTenantlessQuery(ctx)
224223
ctx, query = instrumentQuery(ctx, query, len(args))
225224
return n.execerContext.ExecContext(ctx, query, args)
226225
}
227226

228227
func (n *extendedConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
229-
pprofCheckTenantlessQuery(ctx)
230228
ctx, query = instrumentQuery(ctx, query, len(args))
231229
return n.queryerContext.QueryContext(ctx, query, args)
232230
}

internal/database/dbconn/tenant_pprof.go

Lines changed: 0 additions & 33 deletions
This file was deleted.

internal/diskcache/cache.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"log" //nolint:logging // TODO move all logging to sourcegraph/log
1111
"os"
1212
"path/filepath"
13-
"runtime"
1413
"sort"
1514
"strconv"
1615
"strings"
@@ -205,11 +204,6 @@ func (s *store) OpenWithPath(ctx context.Context, key []string, fetcher FetcherW
205204

206205
// path returns the path for key.
207206
func (s *store) path(ctx context.Context, key []string) (string, error) {
208-
if tenant.ShouldLogNoTenant() {
209-
if _, err := tenant.FromContext(ctx); err != nil {
210-
log.Printf("diskcache: %s:\n%s\n", err, captureStackTrace())
211-
}
212-
}
213207
if !tenant.EnforceTenant() {
214208
return s.pathNoTenant(key), nil
215209
}
@@ -434,15 +428,3 @@ func fsync(path string) error {
434428
}
435429
return err
436430
}
437-
438-
func captureStackTrace() string {
439-
// Allocate a large enough buffer to capture the stack trace
440-
buf := make([]byte, 1024)
441-
for {
442-
n := runtime.Stack(buf, false)
443-
if n < len(buf) {
444-
return string(buf[:n])
445-
}
446-
buf = make([]byte, len(buf)*2)
447-
}
448-
}

internal/tenant/context.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package tenant
22

33
import (
44
"context"
5+
"runtime/pprof"
56

67
"go.uber.org/atomic"
78

@@ -20,6 +21,14 @@ var ErrNoTenantInContext = errors.New("no tenant in context")
2021
func FromContext(ctx context.Context) (*Tenant, error) {
2122
tnt, ok := ctx.Value(tenantKey).(*Tenant)
2223
if !ok {
24+
if pprofMissingTenant != nil {
25+
// We want to track every stack trace, so need a unique value for the event
26+
eventValue := pprofUniqID.Add(1)
27+
28+
// skip stack for Add and this function (2).
29+
pprofMissingTenant.Add(eventValue, 2)
30+
}
31+
2332
return nil, ErrNoTenantInContext
2433
}
2534
return tnt, nil
@@ -73,3 +82,11 @@ func NewTestContext() context.Context {
7382
}
7483
return withTenant(context.Background(), int(tenantCounter.Inc()))
7584
}
85+
86+
var pprofUniqID atomic.Int64
87+
var pprofMissingTenant = func() *pprof.Profile {
88+
if !shouldLogNoTenant() {
89+
return nil
90+
}
91+
return pprof.NewProfile("missing_tenant")
92+
}()

internal/tenant/enforcement.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import (
99

1010
var enforcementMode = env.Get("SRC_TENANT_ENFORCEMENT_MODE", "disabled", "INTERNAL: enforcement mode for tenant isolation. Valid values: disabled, logging, strict")
1111

12-
// ShouldLogNoTenant returns true if the tenant enforcement mode is logging or strict.
12+
// shouldLogNoTenant returns true if the tenant enforcement mode is logging or strict.
1313
// It is used to log a warning if a request to a low-level store is made without a tenant
1414
// so we can identify missing tenants. This will go away and only strict will be allowed
1515
// once we are confident that all contexts carry tenants.
16-
func ShouldLogNoTenant() bool {
16+
func shouldLogNoTenant() bool {
1717
switch enforcementMode {
1818
case "logging", "strict":
1919
return true

0 commit comments

Comments
 (0)