| 1 | 1 |
|
| 2 | 2 |
import (
|
| 3 | 3 |
"io"
|
|
4 |
"io/ioutil"
|
| 4 | 5 |
"time"
|
| 5 | 6 |
)
|
| 6 | 7 |
|
| 7 | 8 |
type proxyReader struct {
|
| 8 | 9 |
io.ReadCloser
|
| 9 | 10 |
bar *Bar
|
| 10 | |
iT time.Time
|
| 11 | 11 |
}
|
| 12 | 12 |
|
| 13 | |
func (prox *proxyReader) Read(p []byte) (int, error) {
|
| 14 | |
n, err := prox.ReadCloser.Read(p)
|
| 15 | |
if n > 0 {
|
| 16 | |
prox.bar.IncrBy(n)
|
| 17 | |
prox.bar.DecoratorEwmaUpdate(time.Since(prox.iT))
|
| 18 | |
prox.iT = time.Now()
|
| 19 | |
}
|
|
13 |
func (x *proxyReader) Read(p []byte) (int, error) {
|
|
14 |
n, err := x.ReadCloser.Read(p)
|
|
15 |
x.bar.IncrBy(n)
|
| 20 | 16 |
if err == io.EOF {
|
| 21 | |
go prox.bar.SetTotal(0, true)
|
|
17 |
go x.bar.SetTotal(0, true)
|
| 22 | 18 |
}
|
| 23 | 19 |
return n, err
|
| 24 | 20 |
}
|
| 25 | 21 |
|
| 26 | 22 |
type proxyWriterTo struct {
|
| 27 | |
*proxyReader
|
| 28 | |
wt io.WriterTo
|
|
23 |
io.ReadCloser // *proxyReader
|
|
24 |
wt io.WriterTo
|
|
25 |
bar *Bar
|
| 29 | 26 |
}
|
| 30 | 27 |
|
| 31 | |
func (prox *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
| 32 | |
n, err := prox.wt.WriteTo(w)
|
| 33 | |
if n > 0 {
|
| 34 | |
prox.bar.IncrInt64(n)
|
| 35 | |
prox.bar.DecoratorEwmaUpdate(time.Since(prox.iT))
|
| 36 | |
prox.iT = time.Now()
|
| 37 | |
}
|
|
28 |
func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
|
29 |
n, err := x.wt.WriteTo(w)
|
|
30 |
x.bar.IncrInt64(n)
|
| 38 | 31 |
if err == io.EOF {
|
| 39 | |
go prox.bar.SetTotal(0, true)
|
|
32 |
go x.bar.SetTotal(0, true)
|
| 40 | 33 |
}
|
| 41 | 34 |
return n, err
|
| 42 | 35 |
}
|
|
36 |
|
|
37 |
type ewmaProxyReader struct {
|
|
38 |
io.ReadCloser // *proxyReader
|
|
39 |
bar *Bar
|
|
40 |
iT time.Time
|
|
41 |
}
|
|
42 |
|
|
43 |
func (x *ewmaProxyReader) Read(p []byte) (int, error) {
|
|
44 |
n, err := x.ReadCloser.Read(p)
|
|
45 |
if n > 0 {
|
|
46 |
x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
|
|
47 |
x.iT = time.Now()
|
|
48 |
}
|
|
49 |
return n, err
|
|
50 |
}
|
|
51 |
|
|
52 |
type ewmaProxyWriterTo struct {
|
|
53 |
io.ReadCloser // *ewmaProxyReader
|
|
54 |
wt io.WriterTo // *proxyWriterTo
|
|
55 |
bar *Bar
|
|
56 |
iT time.Time
|
|
57 |
}
|
|
58 |
|
|
59 |
func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
|
|
60 |
n, err := x.wt.WriteTo(w)
|
|
61 |
if n > 0 {
|
|
62 |
x.bar.DecoratorEwmaUpdate(time.Since(x.iT))
|
|
63 |
x.iT = time.Now()
|
|
64 |
}
|
|
65 |
return n, err
|
|
66 |
}
|
|
67 |
|
|
68 |
func newProxyReader(r io.Reader, bar *Bar) io.ReadCloser {
|
|
69 |
wt, isWriterTo := r.(io.WriterTo)
|
|
70 |
rc := toReadCloser(r)
|
|
71 |
rc = &proxyReader{rc, bar}
|
|
72 |
|
|
73 |
if bar.hasEwmaDecorators {
|
|
74 |
now := time.Now()
|
|
75 |
rc = &ewmaProxyReader{rc, bar, now}
|
|
76 |
if isWriterTo {
|
|
77 |
rc = &ewmaProxyWriterTo{rc, wt, bar, now}
|
|
78 |
}
|
|
79 |
} else if isWriterTo {
|
|
80 |
rc = &proxyWriterTo{rc, wt, bar}
|
|
81 |
}
|
|
82 |
return rc
|
|
83 |
}
|
|
84 |
|
|
85 |
func toReadCloser(r io.Reader) io.ReadCloser {
|
|
86 |
if rc, ok := r.(io.ReadCloser); ok {
|
|
87 |
return rc
|
|
88 |
}
|
|
89 |
return ioutil.NopCloser(r)
|
|
90 |
}
|