pulumi/sdk/go/common/diag
Abhinav Gupta bae69f4c7c
go/common: Make DefaultSink thread-safe
diag.DefaultSink is not safe for concurrent use.
Whether we use it with os.File or with a bytes.Buffer,
both targets do not synchronize their writes,
so this leaves room for interleaving of messages.
Making diag.DefaultSink thread-safe is generally desirable,
but is also a requirement for #12438
so that it can run upgrades concurrently
and print warnings as tasks fail.

This makes the result of DefaultSink thread-safe
by adding a mutex around the targeted stdout and stderr.

Note:
As a special case, when stdout and stderr are the same
we want to use the same mutex for them.
This matches the behavior of [os/exec.Cmd][1]

    // If Stdout and Stderr are the same writer, and have a type that can
    // be compared with ==, at most one goroutine at a time will call Write.
    Stdout io.Writer
    Stderr io.Writer

  [1]: https://pkg.go.dev/os/exec#Cmd

A writer implementation can be anything,
and is not guaranteed to be comparable with `==`.
When that happens, the `==` will panic.
To prevent regressions, we have to handle that case
and treat uncomparable writers as different.
This is also similar to how os/exec does it:
https://cs.opensource.google/go/go/+/refs/tags/go1.20.2:src/os/exec/exec.go;l=475
2023-03-24 08:34:35 -07:00
..
colors all: Reformat with gofumpt 2023-03-03 09:00:24 -08:00
diag.go [breaking] Changing the version of go.mod in sdk / pkg to be v3 2021-04-14 19:32:18 +01:00
errors.go Check for duplicate aliases and plain URNs 2022-11-01 13:40:05 +00:00
sink.go go/common: Make DefaultSink thread-safe 2023-03-24 08:34:35 -07:00
sink_test.go go/common: Make DefaultSink thread-safe 2023-03-24 08:34:35 -07:00