Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03c783ba53 |
@@ -48,7 +48,7 @@ logger to carry `module` and `path` automatically.
|
|||||||
func NewPool(ctx context.Context, id string, handler slog.Handler) (*Pool, error) {
|
func NewPool(ctx context.Context, id string, handler slog.Handler) (*Pool, error) {
|
||||||
ctx = component.MustNew(ctx, "honeybee", "outbound_pool")
|
ctx = component.MustNew(ctx, "honeybee", "outbound_pool")
|
||||||
|
|
||||||
c := component.FromContext(ctx)
|
c, _ := component.Get(ctx)
|
||||||
logger := slog.New(handler).With(slog.Any("component", c), slog.String("pool_id", id))
|
logger := slog.New(handler).With(slog.Any("component", c), slog.String("pool_id", id))
|
||||||
|
|
||||||
return &Pool{ctx: ctx, logger: logger}, nil
|
return &Pool{ctx: ctx, logger: logger}, nil
|
||||||
@@ -64,7 +64,7 @@ path. No parent identifiers need to be passed as arguments.
|
|||||||
func NewWorker(ctx context.Context, id string, handler slog.Handler) (*Worker, error) {
|
func NewWorker(ctx context.Context, id string, handler slog.Handler) (*Worker, error) {
|
||||||
ctx = component.MustExtend(ctx, "outbound_worker")
|
ctx = component.MustExtend(ctx, "outbound_worker")
|
||||||
|
|
||||||
c := component.FromContext(ctx)
|
c, _ := component.Get(ctx)
|
||||||
logger := slog.New(handler).With(slog.Any("component", c), slog.Any("peer_id", id))
|
logger := slog.New(handler).With(slog.Any("component", c), slog.Any("peer_id", id))
|
||||||
|
|
||||||
return &Worker{ctx: ctx, logger: logger}, nil
|
return &Worker{ctx: ctx, logger: logger}, nil
|
||||||
@@ -76,17 +76,19 @@ At the connection layer, another `MustExtend` call extends the path to
|
|||||||
|
|
||||||
### Usage Notes
|
### Usage Notes
|
||||||
|
|
||||||
**Error-Returning vs Panic Variants**:
|
**Function Variants**:
|
||||||
|
|
||||||
- Use `New` and `Extend` when a missing or invalid component is a recoverable
|
- Use `New` and `Extend` when a missing or invalid component is a recoverable
|
||||||
condition.
|
condition.
|
||||||
- Use `MustNew` and `MustExtend` at library boundaries where a missing
|
- Use `MustNew` and `MustExtend` at library boundaries where a missing
|
||||||
component is a programming error that should halt execution immediately.
|
component is a programming error that should halt execution immediately.
|
||||||
|
- Use `TryExtend` if you only want to extend a component if it exists,
|
||||||
|
otherwise use the parent context as-is.
|
||||||
|
|
||||||
**Generic Output**:
|
**Generic Output**:
|
||||||
|
|
||||||
`FieldsFromContext` provides the component fields as a `map[string]string` for non-slog
|
`GetFields` provides the component fields as a `map[string]string` for non-slog
|
||||||
consumers such as OpenTelemetry or Prometheus. It returns `nil` if no component is present.
|
consumers such as OpenTelemetry or Prometheus.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
|||||||
@@ -42,25 +42,23 @@ func insert(ctx context.Context, module string, name string, path []string) cont
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromContext retrieves the current component from the context; returns nil if none is present.
|
// Get retrieves the current component from the context; returns false if none is present.
|
||||||
func FromContext(ctx context.Context) Component {
|
func Get(ctx context.Context) (Component, bool) {
|
||||||
c, ok := ctx.Value(storageKey).(component)
|
t, ok := ctx.Value(storageKey).(component)
|
||||||
if !ok {
|
return t, ok
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FieldsFromContext returns the component as a string map with keys "module" and "path"; returns nil if none is present.
|
// GetFields returns the component as a string map with keys "module" and "path".
|
||||||
func FieldsFromContext(ctx context.Context) map[string]string {
|
func GetFields(ctx context.Context) (map[string]string, bool) {
|
||||||
c := FromContext(ctx)
|
c, ok := Get(ctx)
|
||||||
if c == nil {
|
if !ok {
|
||||||
return nil
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"module": c.Module(),
|
"module": c.Module(),
|
||||||
"path": c.PathString(),
|
"path": c.PathString(),
|
||||||
}
|
}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
// New sets a new component on the context, resetting any existing component.
|
// New sets a new component on the context, resetting any existing component.
|
||||||
@@ -83,8 +81,8 @@ func Extend(ctx context.Context, name string) (context.Context, error) {
|
|||||||
return nil, fmt.Errorf("context is nil")
|
return nil, fmt.Errorf("context is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := FromContext(ctx)
|
c, ok := Get(ctx)
|
||||||
if c == nil {
|
if !ok {
|
||||||
return nil, fmt.Errorf("missing parent component")
|
return nil, fmt.Errorf("missing parent component")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +93,21 @@ func Extend(ctx context.Context, name string) (context.Context, error) {
|
|||||||
return insert(ctx, c.Module(), name, c.Path()), nil
|
return insert(ctx, c.Module(), name, c.Path()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TryExtend returns ctx if no parent component is attached, otherwise
|
||||||
|
// extends the existing component path.
|
||||||
|
func TryExtend(ctx context.Context, name string) (context.Context, error) {
|
||||||
|
if ctx == nil {
|
||||||
|
return nil, fmt.Errorf("context is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
c, ok := Get(ctx)
|
||||||
|
if !ok || name == "" {
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return insert(ctx, c.Module(), name, c.Path()), nil
|
||||||
|
}
|
||||||
|
|
||||||
// MustNew is New but panics on error.
|
// MustNew is New but panics on error.
|
||||||
func MustNew(ctx context.Context, module string, name string) context.Context {
|
func MustNew(ctx context.Context, module string, name string) context.Context {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
@@ -115,8 +128,8 @@ func MustExtend(ctx context.Context, name string) context.Context {
|
|||||||
panic("context is nil")
|
panic("context is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := FromContext(ctx)
|
c, ok := Get(ctx)
|
||||||
if c == nil {
|
if !ok {
|
||||||
panic("missing parent component")
|
panic("missing parent component")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+26
-12
@@ -22,8 +22,8 @@ func TestNew(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error, got %v", err)
|
t.Fatalf("expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
c := FromContext(ctx)
|
c, ok := Get(ctx)
|
||||||
if c == nil {
|
if !ok {
|
||||||
t.Fatal("expected component in context")
|
t.Fatal("expected component in context")
|
||||||
}
|
}
|
||||||
if c.Module() != "mymodule" {
|
if c.Module() != "mymodule" {
|
||||||
@@ -58,8 +58,8 @@ func TestExtend(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("expected no error, got %v", err)
|
t.Fatalf("expected no error, got %v", err)
|
||||||
}
|
}
|
||||||
c := FromContext(ctx)
|
c, ok := Get(ctx)
|
||||||
if c == nil {
|
if !ok {
|
||||||
t.Fatal("expected component in context")
|
t.Fatal("expected component in context")
|
||||||
}
|
}
|
||||||
if c.Module() != "mymodule" {
|
if c.Module() != "mymodule" {
|
||||||
@@ -80,6 +80,17 @@ func TestExtend(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("try passes through", func(t *testing.T) {
|
||||||
|
inCtx := context.Background()
|
||||||
|
outCtx, err := TryExtend(inCtx, "subcomponent")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("unexpected error:", err)
|
||||||
|
}
|
||||||
|
if outCtx != inCtx {
|
||||||
|
t.Errorf("expected context to pass through")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("must variant should panic", func(t *testing.T) {
|
t.Run("must variant should panic", func(t *testing.T) {
|
||||||
assertPanics(t, func() {
|
assertPanics(t, func() {
|
||||||
MustExtend(context.Background(), "subcomponent")
|
MustExtend(context.Background(), "subcomponent")
|
||||||
@@ -87,25 +98,28 @@ func TestExtend(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromContext(t *testing.T) {
|
func TestGet(t *testing.T) {
|
||||||
if FromContext(context.Background()) != nil {
|
_, ok := Get(context.Background())
|
||||||
|
if ok {
|
||||||
t.Fatal("expected no component on bare context")
|
t.Fatal("expected no component on bare context")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
||||||
if FromContext(ctx) == nil {
|
_, ok = Get(ctx)
|
||||||
|
if !ok {
|
||||||
t.Fatal("expected component in context")
|
t.Fatal("expected component in context")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFieldsFromContext(t *testing.T) {
|
func TestGetFields(t *testing.T) {
|
||||||
if FieldsFromContext(context.Background()) != nil {
|
_, ok := GetFields(context.Background())
|
||||||
|
if ok {
|
||||||
t.Fatal("expected no fields on bare context")
|
t.Fatal("expected no fields on bare context")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
||||||
fields := FieldsFromContext(ctx)
|
fields, ok := GetFields(ctx)
|
||||||
if fields == nil {
|
if !ok {
|
||||||
t.Fatal("expected fields in context")
|
t.Fatal("expected fields in context")
|
||||||
}
|
}
|
||||||
if fields["module"] != "mymodule" {
|
if fields["module"] != "mymodule" {
|
||||||
@@ -118,7 +132,7 @@ func TestFieldsFromContext(t *testing.T) {
|
|||||||
|
|
||||||
func TestLogValue(t *testing.T) {
|
func TestLogValue(t *testing.T) {
|
||||||
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
ctx := MustNew(context.Background(), "mymodule", "mycomponent")
|
||||||
c := FromContext(ctx)
|
c, _ := Get(ctx)
|
||||||
v := c.LogValue()
|
v := c.LogValue()
|
||||||
attrs := v.Group()
|
attrs := v.Group()
|
||||||
if len(attrs) != 2 {
|
if len(attrs) != 2 {
|
||||||
|
|||||||
Reference in New Issue
Block a user