Skip to content

Commit 6088d5b

Browse files
committed
slog-handler-guide: discuss Record.Clone
Change-Id: I55c6367da953b9a59c4d5cd8ca817d3c051e12de Reviewed-on: https://go-review.googlesource.com/c/example/+/513138 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Cottrell <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]>
1 parent b766721 commit 6088d5b

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

slog-handler-guide/README.md

+39-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ This document is maintained by Jonathan Amsterdam `[email protected]`.
1616
1. [The `WithGroup` method](#the-`withgroup`-method)
1717
1. [Testing](#testing)
1818
1. [General considerations](#general-considerations)
19+
1. [Copying records](#copying-records)
1920
1. [Concurrency safety](#concurrency-safety)
2021
1. [Robustness](#robustness)
2122
1. [Speed](#speed)
@@ -766,7 +767,44 @@ in 65 lines.
766767

767768
# General considerations
768769

769-
TODO(jba): reintroduce the material on Record.Clone that used to be here.
770+
## Copying records
771+
772+
Most handlers won't need to copy the `slog.Record` that is passed
773+
to the `Handle` method.
774+
Those that do must take special care in some cases.
775+
776+
A handler can make a single copy of a `Record` with an ordinary Go
777+
assignment, channel send or function call if it doesn't retain the
778+
original.
779+
But if its actions result in more than one copy, it should call `Record.Clone`
780+
to make the copies so that they don't share state.
781+
This `Handle` method passes the record to a single handler, so it doesn't require `Clone`:
782+
783+
type Handler1 struct {
784+
h slog.Handler
785+
// ...
786+
}
787+
788+
func (h *Handler1) Handle(ctx context.Context, r slog.Record) error {
789+
return h.h.Handle(ctx, r)
790+
}
791+
792+
This `Handle` method might pass the record to more than one handler, so it
793+
should use `Clone`:
794+
795+
type Handler2 struct {
796+
hs []slog.Handler
797+
// ...
798+
}
799+
800+
func (h *Handler2) Handle(ctx context.Context, r slog.Record) error {
801+
for _, hh := range h.hs {
802+
if err := hh.Handle(ctx, r.Clone()); err != nil {
803+
return err
804+
}
805+
}
806+
return nil
807+
}
770808

771809
## Concurrency safety
772810

slog-handler-guide/guide.md

+38-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,44 @@ in 65 lines.
485485

486486
# General considerations
487487

488-
TODO(jba): reintroduce the material on Record.Clone that used to be here.
488+
## Copying records
489+
490+
Most handlers won't need to copy the `slog.Record` that is passed
491+
to the `Handle` method.
492+
Those that do must take special care in some cases.
493+
494+
A handler can make a single copy of a `Record` with an ordinary Go
495+
assignment, channel send or function call if it doesn't retain the
496+
original.
497+
But if its actions result in more than one copy, it should call `Record.Clone`
498+
to make the copies so that they don't share state.
499+
This `Handle` method passes the record to a single handler, so it doesn't require `Clone`:
500+
501+
type Handler1 struct {
502+
h slog.Handler
503+
// ...
504+
}
505+
506+
func (h *Handler1) Handle(ctx context.Context, r slog.Record) error {
507+
return h.h.Handle(ctx, r)
508+
}
509+
510+
This `Handle` method might pass the record to more than one handler, so it
511+
should use `Clone`:
512+
513+
type Handler2 struct {
514+
hs []slog.Handler
515+
// ...
516+
}
517+
518+
func (h *Handler2) Handle(ctx context.Context, r slog.Record) error {
519+
for _, hh := range h.hs {
520+
if err := hh.Handle(ctx, r.Clone()); err != nil {
521+
return err
522+
}
523+
}
524+
return nil
525+
}
489526

490527
## Concurrency safety
491528

0 commit comments

Comments
 (0)