Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit cdd47ca

Browse files
Merge pull request go-kit#501 from go-kit/fdsync
log: Update NewSyncWriter to work with term.IsTerminal.
2 parents 04dd4f7 + 22ff154 commit cdd47ca

File tree

2 files changed

+61
-15
lines changed

2 files changed

+61
-15
lines changed

‎log/sync.go‎

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package log
1+
package log
22

33
import (
44
"io"
@@ -36,24 +36,59 @@ func (l *SwapLogger) Swap(logger Logger) {
3636
l.logger.Store(loggerStruct{logger})
3737
}
3838

39-
// SyncWriter synchronizes concurrent writes to an io.Writer.
40-
type SyncWriter struct {
41-
mu sync.Mutex
42-
w io.Writer
39+
// NewSyncWriter returns a new writer that is safe for concurrent use by
40+
// multiple goroutines. Writes to the returned writer are passed on to w. If
41+
// another write is already in progress, the calling goroutine blocks until
42+
// the writer is available.
43+
//
44+
// If w implements the following interface, so does the returned writer.
45+
//
46+
// interface {
47+
// Fd() uintptr
48+
// }
49+
func NewSyncWriter(w io.Writer) io.Writer {
50+
switch w := w.(type) {
51+
case fdWriter:
52+
return &fdSyncWriter{fdWriter: w}
53+
default:
54+
return &syncWriter{Writer: w}
55+
}
56+
}
57+
58+
// syncWriter synchronizes concurrent writes to an io.Writer.
59+
type syncWriter struct {
60+
sync.Mutex
61+
io.Writer
62+
}
63+
64+
// Write writes p to the underlying io.Writer. If another write is already in
65+
// progress, the calling goroutine blocks until the syncWriter is available.
66+
func (w *syncWriter) Write(p []byte) (n int, err error) {
67+
w.Lock()
68+
n, err = w.Writer.Write(p)
69+
w.Unlock()
70+
return n, err
71+
}
72+
73+
// fdWriter is an io.Writer that also has an Fd method. The most common
74+
// example of an fdWriter is an *os.File.
75+
type fdWriter interface {
76+
io.Writer
77+
Fd() uintptr
4378
}
4479

45-
// NewSyncWriter returns a new SyncWriter. The returned writer is safe for
46-
// concurrent use by multiple goroutines.
47-
funcNewSyncWriter(w io.Writer) *SyncWriter {
48-
return&SyncWriter{w: w}
80+
// fdSyncWriter synchronizes concurrent writes to an fdWriter.
81+
typefdSyncWriterstruct {
82+
sync.Mutex
83+
fdWriter
4984
}
5085

5186
// Write writes p to the underlying io.Writer. If another write is already in
52-
// progress, the calling goroutine blocks until the SyncWriter is available.
53-
func (w *SyncWriter) Write(p []byte) (n int, err error) {
54-
w.mu.Lock()
55-
n, err = w.w.Write(p)
56-
w.mu.Unlock()
87+
// progress, the calling goroutine blocks until the fdSyncWriter is available.
88+
func (w *fdSyncWriter) Write(p []byte) (n int, err error) {
89+
w.Lock()
90+
n, err = w.fdWriter.Write(p)
91+
w.Unlock()
5792
return n, err
5893
}
5994

‎log/sync_test.go‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
package log_test
1+
package log_test
22

33
import (
44
"bytes"
55
"io"
6+
"os"
67
"testing"
78

89
"github.com/go-kit/kit/log"
@@ -70,3 +71,13 @@ func TestSyncWriterConcurrency(t *testing.T) {
7071
w = log.NewSyncWriter(w)
7172
testConcurrency(t, log.NewLogfmtLogger(w), 10000)
7273
}
74+
75+
func TestSyncWriterFd(t *testing.T) {
76+
_, ok := log.NewSyncWriter(os.Stdout).(interface {
77+
Fd() uintptr
78+
})
79+
80+
if !ok {
81+
t.Error("NewSyncWriter does not pass through Fd method")
82+
}
83+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /