Skip to content

Commit b6dc811

Browse files
committed
Add Read and Write counters. Fix lint. Update build/test.
1 parent 09802d7 commit b6dc811

File tree

12 files changed

+148
-70
lines changed

12 files changed

+148
-70
lines changed

.gitignore

Lines changed: 0 additions & 15 deletions
This file was deleted.

.travis.yml

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
1+
# Simple go lint and test.
2+
os: linux
3+
dist: bionic
14
language: go
2-
sudo: false
3-
45
go:
5-
- "1.11"
6-
- "1.12"
7-
- "1.13"
8-
- "master"
9-
10-
matrix:
11-
allow_failures:
12-
- go: master
13-
6+
- 1.17.x
147
install:
15-
- go install
16-
- go get -u golang.org/x/lint/golint
17-
8+
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.43.0
189
script:
19-
- go test -v ./...
20-
- diff <(golint *.go) <(printf "")
10+
- make test

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
The MIT License (MIT)
22

33
Copyright (c) 2015 Artem Andreenko <mio@volmy.com>
4+
Copyright (c) 2022 Go Lift <code@golift.io>
45

56
Permission is hereby granted, free of charge, to any person obtaining a copy
67
of this software and associated documentation files (the "Software"), to deal
@@ -19,4 +20,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1920
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2021
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2122
SOFTWARE.
22-

Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
all:
2+
@echo "try: make test"
3+
4+
test: lint
5+
go test -race -covermode=atomic ./...
6+
# Test 32 bit OSes.
7+
GOOS=linux GOARCH=386 go build .
8+
GOOS=freebsd GOARCH=386 go build .
9+
10+
lint:
11+
# Test lint on four platforms.
12+
GOOS=linux golangci-lint run --enable-all -D maligned,scopelint,interfacer,golint
13+
GOOS=darwin golangci-lint run --enable-all -D maligned,scopelint,interfacer,golint
14+
GOOS=windows golangci-lint run --enable-all -D maligned,scopelint,interfacer,golint
15+
GOOS=freebsd golangci-lint run --enable-all -D maligned,scopelint,interfacer,golint

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@
22

33
Golang counters for readers/writers.
44

5-
[![Build Status](https://travis-ci.org/miolini/datacounter.svg)](https://travis-ci.org/miolini/datacounter) [![GoDoc](https://godoc.org/github.com/miolini/datacounter?status.svg)](http://godoc.org/github.com/miolini/datacounter)
5+
[![Build Status](https://travis-ci.org/golift/datacounter.svg)](https://travis-ci.org/golift/datacounter)
6+
7+
[GoDoc](http://godoc.org/github.com/golift/datacounter)
8+
9+
## Fork?
10+
11+
This fork adds `.Read()` and `.Write()` method counters in addition to the existing byte counters.
612

713
## Examples
814

915
### ReaderCounter
1016

1117
```go
18+
19+
import "golift.io/datacounter"
20+
1221
buf := bytes.Buffer{}
1322
buf.Write(data)
1423
counter := datacounter.NewReaderCounter(&buf)
@@ -22,6 +31,8 @@ if counter.Count() != dataLen {
2231
### WriterCounter
2332

2433
```go
34+
import "golift.io/datacounter"
35+
2536
buf := bytes.Buffer{}
2637
counter := datacounter.NewWriterCounter(&buf)
2738

@@ -34,6 +45,8 @@ if counter.Count() != dataLen {
3445
### http.ResponseWriter Counter
3546

3647
```go
48+
import "golift.io/datacounter"
49+
3750
handler := func(w http.ResponseWriter, r *http.Request) {
3851
w.Write(data)
3952
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
module github.com/miolini/datacounter
1+
module golift.io/datacounter
22

3-
go 1.11
3+
go 1.17

reader.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,37 @@ import (
55
"sync/atomic"
66
)
77

8-
// ReaderCounter is counter for io.Reader
8+
// ReaderCounter is counter for io.Reader.
99
type ReaderCounter struct {
1010
io.Reader
1111
count uint64
12+
reads uint64
1213
}
1314

14-
// NewReaderCounter function for create new ReaderCounter
15+
// NewReaderCounter function for create new ReaderCounter.
1516
func NewReaderCounter(r io.Reader) *ReaderCounter {
1617
return &ReaderCounter{
1718
Reader: r,
19+
count: 0,
20+
reads: 0,
1821
}
1922
}
2023

24+
// Reads counts bytes read and increments read counter.
2125
func (counter *ReaderCounter) Read(buf []byte) (int, error) {
2226
n, err := counter.Reader.Read(buf)
2327
atomic.AddUint64(&counter.count, uint64(n))
24-
return n, err
28+
atomic.AddUint64(&counter.reads, 1)
29+
30+
return n, err //nolint:wrapcheck
2531
}
2632

27-
// Count function return counted bytes
33+
// Count function returns count of bytes read.
2834
func (counter *ReaderCounter) Count() uint64 {
2935
return atomic.LoadUint64(&counter.count)
3036
}
37+
38+
// Reads function returns count of calls to Read() method.
39+
func (counter *ReaderCounter) Reads() uint64 {
40+
return atomic.LoadUint64(&counter.reads)
41+
}

reader_test.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
package datacounter
1+
package datacounter_test
22

33
import (
44
"bytes"
55
"io"
66
"io/ioutil"
77
"testing"
8-
)
98

10-
var data = []byte("Hello, World!")
11-
var dataLen = uint64(len(data))
9+
"golift.io/datacounter"
10+
)
1211

1312
func TestReaderCounter(t *testing.T) {
13+
t.Parallel()
14+
15+
var (
16+
data = []byte("Hello, World!")
17+
dataLen = uint64(len(data))
18+
)
19+
1420
buf := bytes.Buffer{}
15-
buf.Write(data)
16-
counter := NewReaderCounter(&buf)
17-
io.Copy(ioutil.Discard, counter)
21+
_, _ = buf.Write(data)
22+
counter := datacounter.NewReaderCounter(&buf)
23+
_, _ = io.Copy(ioutil.Discard, counter)
24+
1825
if counter.Count() != dataLen {
1926
t.Fatalf("count mismatch len of test data: %d != %d", counter.Count(), len(data))
2027
}
28+
29+
if counter.Reads() != 2 {
30+
t.Fatalf("reads mismatch len of test data: %d != 1", counter.Reads())
31+
}
2132
}

response_writer.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,67 @@ import (
99
"time"
1010
)
1111

12-
// ResponseWriterCounter is counter for http.ResponseWriter
12+
// ResponseWriterCounter is counter for http.ResponseWriter.
1313
type ResponseWriterCounter struct {
1414
http.ResponseWriter
1515
count uint64
16+
writes uint64
1617
started time.Time
1718
statusCode int
1819
}
1920

20-
// NewResponseWriterCounter function create new ResponseWriterCounter
21+
// NewResponseWriterCounter function create new ResponseWriterCounter.
2122
func NewResponseWriterCounter(rw http.ResponseWriter) *ResponseWriterCounter {
2223
return &ResponseWriterCounter{
2324
ResponseWriter: rw,
2425
started: time.Now(),
26+
statusCode: 0,
27+
count: 0,
28+
writes: 0,
2529
}
2630
}
2731

28-
// Write returns underlying Write result, while counting data size
32+
// Write returns underlying Write result, while counting data size.
2933
func (counter *ResponseWriterCounter) Write(buf []byte) (int, error) {
3034
n, err := counter.ResponseWriter.Write(buf)
3135
atomic.AddUint64(&counter.count, uint64(n))
32-
return n, err
36+
atomic.AddUint64(&counter.writes, 1)
37+
38+
return n, err //nolint:wrapcheck
3339
}
3440

35-
// Header returns underlying Header result
41+
// Header returns underlying Header result.
3642
func (counter *ResponseWriterCounter) Header() http.Header {
3743
return counter.ResponseWriter.Header()
3844
}
3945

40-
// WriteHeader returns underlying WriteHeader, while setting Runtime header
46+
// WriteHeader returns underlying WriteHeader, while setting Runtime header.
4147
func (counter *ResponseWriterCounter) WriteHeader(statusCode int) {
4248
counter.Header().Set("X-Runtime", fmt.Sprintf("%.6f", time.Since(counter.started).Seconds()))
4349
counter.ResponseWriter.WriteHeader(statusCode)
4450
}
4551

46-
// Hijack returns underlying Hijack
52+
// Hijack returns underlying Hijack.
4753
func (counter *ResponseWriterCounter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
48-
return counter.ResponseWriter.(http.Hijacker).Hijack()
54+
return counter.ResponseWriter.(http.Hijacker).Hijack() //nolint:wrapcheck
4955
}
5056

51-
// Count function return counted bytes
57+
// Count function return counted bytes.
5258
func (counter *ResponseWriterCounter) Count() uint64 {
5359
return atomic.LoadUint64(&counter.count)
5460
}
5561

56-
// Started returns started value
62+
// Writes function returns count of Write() calls.
63+
func (counter *ResponseWriterCounter) Writes() uint64 {
64+
return atomic.LoadUint64(&counter.writes)
65+
}
66+
67+
// Started returns started value.
5768
func (counter *ResponseWriterCounter) Started() time.Time {
5869
return counter.started
5970
}
6071

61-
// StatusCode returns sent status code
72+
// StatusCode returns sent status code.
6273
func (counter *ResponseWriterCounter) StatusCode() int {
6374
return counter.statusCode
6475
}

response_writer_test.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,40 @@
1-
package datacounter
1+
package datacounter_test
22

33
import (
4+
"context"
45
"net/http"
56
"net/http/httptest"
67
"testing"
8+
9+
"golift.io/datacounter"
710
)
811

912
func TestResponseWriterCounter(t *testing.T) {
10-
handler := func(w http.ResponseWriter, r *http.Request) {
11-
w.Write(data)
13+
t.Parallel()
14+
15+
var (
16+
data = []byte("Hello, World!")
17+
dataLen = uint64(len(data))
18+
)
19+
20+
handler := func(w http.ResponseWriter, _ *http.Request) {
21+
_, _ = w.Write(data)
1222
}
13-
req, err := http.NewRequest("GET", "http://example.com/foo", nil)
23+
24+
req, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com/foo", nil)
1425
if err != nil {
1526
t.Fatal(err)
1627
}
28+
1729
w := httptest.NewRecorder()
18-
counter := NewResponseWriterCounter(w)
30+
counter := datacounter.NewResponseWriterCounter(w)
1931
handler(counter, req)
32+
2033
if counter.Count() != dataLen {
2134
t.Fatalf("count mismatch len of test data: %d != %d", counter.Count(), len(data))
2235
}
36+
37+
if counter.Writes() != 1 {
38+
t.Fatalf("write mismatch len of test data: %d != 1", counter.Writes())
39+
}
2340
}

0 commit comments

Comments
 (0)