Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions pkg/otelutil/otel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package otelutil
import (
"context"
"fmt"
"os"

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc"
Expand All @@ -14,9 +15,14 @@ import (
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
)

// InitTracer creates and registers a TracerProvider with OTLP gRPC exporter.
// Returns a shutdown function.
// InitTracer is a no-op (propagator only) when no OTLP endpoint env var is
// set, to avoid `traces export: connection refused` spam in dev / CI.
func InitTracer(ctx context.Context, serviceName string) (func(context.Context) error, error) {
if os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT") == "" && os.Getenv("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") == "" {
otel.SetTextMapPropagator(propagation.TraceContext{})
return func(context.Context) error { return nil }, nil
}

exp, err := otlptracegrpc.New(ctx)
if err != nil {
return nil, fmt.Errorf("otlp exporter: %w", err)
Expand Down
3 changes: 3 additions & 0 deletions search-service/deploy/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ services:
- SEARCH_RECENT_WINDOW=8760h
- SEARCH_REQUEST_TIMEOUT=10s
- SEARCH_METRICS_ADDR=:9090
# Local dev pins to site-suffixed indices; prod uses aliases owned by ops/IaC.
- SEARCH_USER_ROOM_INDEX=user-room-site-local
- SEARCH_SPOTLIGHT_INDEX=spotlight-site-local-v1-chat
ports:
# Expose /metrics so Prometheus / curl can scrape from the host
# during local dev. The listener is bound on 0.0.0.0:9090 inside
Expand Down
3 changes: 2 additions & 1 deletion search-service/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type handlerConfig struct {
RecentWindow time.Duration
RequestTimeout time.Duration
UserRoomIndex string
SpotlightIndex string
}

type handler struct {
Expand Down Expand Up @@ -136,7 +137,7 @@ func (h *handler) searchRooms(c *natsrouter.Context, req model.SearchRoomsReques
}

observeESDone := observeES()
raw, err := h.store.Search(ctx, []string{SpotlightIndex}, body)
raw, err := h.store.Search(ctx, []string{h.cfg.SpotlightIndex}, body)
observeESDone()
if err != nil {
slog.Error("room search backend failed", "account", account, "error", err)
Expand Down
5 changes: 4 additions & 1 deletion search-service/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/hmchangw/chat/pkg/natsrouter"
)

const testSpotlightIndex = "spotlight"

type fakeStore struct {
searchCalls []searchCall
searchBody json.RawMessage
Expand Down Expand Up @@ -84,6 +86,7 @@ func newTestHandler(store SearchStore, cache RestrictedRoomCache) *handler {
MaxDocCounts: 100,
RestrictedRoomsCacheTTL: 5 * time.Minute,
RecentWindow: 365 * 24 * time.Hour,
SpotlightIndex: testSpotlightIndex,
})
}

Expand Down Expand Up @@ -234,7 +237,7 @@ func TestHandler_SearchRooms_ScopeAllHappyPath(t *testing.T) {
assert.Equal(t, "r1", resp.Results[0].RoomID)

require.Len(t, store.searchCalls, 1)
assert.Equal(t, []string{SpotlightIndex}, store.searchCalls[0].indices)
assert.Equal(t, []string{testSpotlightIndex}, store.searchCalls[0].indices)
}

func TestHandler_SearchRooms_ScopeAppRejected(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions search-service/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func setupCCSFixture(t *testing.T) *ccsFixture {
RestrictedRoomsCacheTTL: 5 * time.Minute,
RecentWindow: 365 * 24 * time.Hour,
UserRoomIndex: userRoomIndex,
SpotlightIndex: "spotlight-test",
})

router := natsrouter.New(serverNC, "search-service-test")
Expand Down
4 changes: 3 additions & 1 deletion search-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ type SearchConfig struct {
RestrictedRoomsCacheTTL time.Duration `env:"RESTRICTED_ROOMS_CACHE_TTL" envDefault:"5m"`
RecentWindow time.Duration `env:"RECENT_WINDOW" envDefault:"8760h"`
RequestTimeout time.Duration `env:"REQUEST_TIMEOUT" envDefault:"10s"`
UserRoomIndex string `env:"USER_ROOM_INDEX" envDefault:""`
UserRoomIndex string `env:"USER_ROOM_INDEX,required"`
SpotlightIndex string `env:"SPOTLIGHT_INDEX,required"`
MetricsAddr string `env:"METRICS_ADDR" envDefault:":9090"`
}

Expand Down Expand Up @@ -116,6 +117,7 @@ func main() {
RecentWindow: cfg.Search.RecentWindow,
RequestTimeout: cfg.Search.RequestTimeout,
UserRoomIndex: cfg.Search.UserRoomIndex,
SpotlightIndex: cfg.Search.SpotlightIndex,
})

router := natsrouter.New(nc, "search-service")
Expand Down
5 changes: 0 additions & 5 deletions search-service/query_rooms.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ import (
"github.com/hmchangw/chat/pkg/natsrouter"
)

// SpotlightIndex is the (local-only) room-typeahead index. Always one
// document per (user, room) pair — the spotlight index keeps search-as-you-
// type docs locally even when messages live on remote sites.
const SpotlightIndex = "spotlight"

// room scope filter values accepted on SearchRoomsRequest.Scope.
const (
scopeAll = "all"
Expand Down
Loading