run golangci-lint and apply suggested fixes
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package bytecounter
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ByteCounterReader struct {
|
||||
reader io.ReadCloser
|
||||
|
||||
// called & accessed synchronously during Read, no external access
|
||||
cb func(full int64)
|
||||
cbEvery time.Duration
|
||||
lastCbAt time.Time
|
||||
|
||||
// set atomically because it may be read by multiple threads
|
||||
bytes int64
|
||||
}
|
||||
|
||||
func NewByteCounterReader(reader io.ReadCloser) *ByteCounterReader {
|
||||
return &ByteCounterReader{
|
||||
reader: reader,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) SetCallback(every time.Duration, cb func(full int64)) {
|
||||
b.cbEvery = every
|
||||
b.cb = cb
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Close() error {
|
||||
return b.reader.Close()
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Read(p []byte) (n int, err error) {
|
||||
n, err = b.reader.Read(p)
|
||||
full := atomic.AddInt64(&b.bytes, int64(n))
|
||||
now := time.Now()
|
||||
if b.cb != nil && now.Sub(b.lastCbAt) > b.cbEvery {
|
||||
b.cb(full)
|
||||
b.lastCbAt = now
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Bytes() int64 {
|
||||
return atomic.LoadInt64(&b.bytes)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package chainedio
|
||||
|
||||
import "io"
|
||||
|
||||
type ChainedReader struct {
|
||||
Readers []io.Reader
|
||||
curReader int
|
||||
}
|
||||
|
||||
func NewChainedReader(reader ...io.Reader) *ChainedReader {
|
||||
return &ChainedReader{
|
||||
Readers: reader,
|
||||
curReader: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChainedReader) Read(buf []byte) (n int, err error) {
|
||||
|
||||
n = 0
|
||||
|
||||
for c.curReader < len(c.Readers) {
|
||||
n, err = c.Readers[c.curReader].Read(buf)
|
||||
if err == io.EOF {
|
||||
c.curReader++
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if c.curReader == len(c.Readers) {
|
||||
err = io.EOF // actually, there was no gap
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package chunking
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -49,7 +49,7 @@ func (c *Unchunker) Read(b []byte) (n int, err error) {
|
||||
|
||||
}
|
||||
|
||||
if c.remainingChunkBytes <= 0 {
|
||||
if c.remainingChunkBytes == 0 {
|
||||
panic("internal inconsistency: c.remainingChunkBytes must be > 0")
|
||||
}
|
||||
if len(b) <= 0 {
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package chunking
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -0,0 +1,67 @@
|
||||
package connlogger
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
type NetConnLogger struct {
|
||||
net.Conn
|
||||
ReadFile *os.File
|
||||
WriteFile *os.File
|
||||
}
|
||||
|
||||
func NewNetConnLogger(conn net.Conn, readlog, writelog string) (l *NetConnLogger, err error) {
|
||||
l = &NetConnLogger{
|
||||
Conn: conn,
|
||||
}
|
||||
flags := os.O_CREATE | os.O_WRONLY
|
||||
if readlog != "" {
|
||||
if l.ReadFile, err = os.OpenFile(readlog, flags, 0600); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if writelog != "" {
|
||||
if l.WriteFile, err = os.OpenFile(writelog, flags, 0600); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NetConnLogger) Read(buf []byte) (n int, err error) {
|
||||
n, err = c.Conn.Read(buf)
|
||||
if c.WriteFile != nil {
|
||||
if _, writeErr := c.ReadFile.Write(buf[0:n]); writeErr != nil {
|
||||
panic(writeErr)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NetConnLogger) Write(buf []byte) (n int, err error) {
|
||||
n, err = c.Conn.Write(buf)
|
||||
if c.ReadFile != nil {
|
||||
if _, writeErr := c.WriteFile.Write(buf[0:n]); writeErr != nil {
|
||||
panic(writeErr)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
func (c *NetConnLogger) Close() (err error) {
|
||||
err = c.Conn.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if c.ReadFile != nil {
|
||||
if err := c.ReadFile.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if c.WriteFile != nil {
|
||||
if err := c.WriteFile.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
-144
@@ -1,144 +0,0 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NetConnLogger struct {
|
||||
net.Conn
|
||||
ReadFile *os.File
|
||||
WriteFile *os.File
|
||||
}
|
||||
|
||||
func NewNetConnLogger(conn net.Conn, readlog, writelog string) (l *NetConnLogger, err error) {
|
||||
l = &NetConnLogger{
|
||||
Conn: conn,
|
||||
}
|
||||
flags := os.O_CREATE | os.O_WRONLY
|
||||
if readlog != "" {
|
||||
if l.ReadFile, err = os.OpenFile(readlog, flags, 0600); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if writelog != "" {
|
||||
if l.WriteFile, err = os.OpenFile(writelog, flags, 0600); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NetConnLogger) Read(buf []byte) (n int, err error) {
|
||||
n, err = c.Conn.Read(buf)
|
||||
if c.WriteFile != nil {
|
||||
if _, writeErr := c.ReadFile.Write(buf[0:n]); writeErr != nil {
|
||||
panic(writeErr)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *NetConnLogger) Write(buf []byte) (n int, err error) {
|
||||
n, err = c.Conn.Write(buf)
|
||||
if c.ReadFile != nil {
|
||||
if _, writeErr := c.WriteFile.Write(buf[0:n]); writeErr != nil {
|
||||
panic(writeErr)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
func (c *NetConnLogger) Close() (err error) {
|
||||
err = c.Conn.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if c.ReadFile != nil {
|
||||
if err := c.ReadFile.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if c.WriteFile != nil {
|
||||
if err := c.WriteFile.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type ChainedReader struct {
|
||||
Readers []io.Reader
|
||||
curReader int
|
||||
}
|
||||
|
||||
func NewChainedReader(reader ...io.Reader) *ChainedReader {
|
||||
return &ChainedReader{
|
||||
Readers: reader,
|
||||
curReader: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ChainedReader) Read(buf []byte) (n int, err error) {
|
||||
|
||||
n = 0
|
||||
|
||||
for c.curReader < len(c.Readers) {
|
||||
n, err = c.Readers[c.curReader].Read(buf)
|
||||
if err == io.EOF {
|
||||
c.curReader++
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if c.curReader == len(c.Readers) {
|
||||
err = io.EOF // actually, there was no gap
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type ByteCounterReader struct {
|
||||
reader io.ReadCloser
|
||||
|
||||
// called & accessed synchronously during Read, no external access
|
||||
cb func(full int64)
|
||||
cbEvery time.Duration
|
||||
lastCbAt time.Time
|
||||
bytesSinceLastCb int64
|
||||
|
||||
// set atomically because it may be read by multiple threads
|
||||
bytes int64
|
||||
}
|
||||
|
||||
func NewByteCounterReader(reader io.ReadCloser) *ByteCounterReader {
|
||||
return &ByteCounterReader{
|
||||
reader: reader,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) SetCallback(every time.Duration, cb func(full int64)) {
|
||||
b.cbEvery = every
|
||||
b.cb = cb
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Close() error {
|
||||
return b.reader.Close()
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Read(p []byte) (n int, err error) {
|
||||
n, err = b.reader.Read(p)
|
||||
full := atomic.AddInt64(&b.bytes, int64(n))
|
||||
now := time.Now()
|
||||
if b.cb != nil && now.Sub(b.lastCbAt) > b.cbEvery {
|
||||
b.cb(full)
|
||||
b.lastCbAt = now
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (b *ByteCounterReader) Bytes() int64 {
|
||||
return atomic.LoadInt64(&b.bytes)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package iocommand
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -99,7 +99,7 @@ func (c *IOCommand) doWait(ctx context.Context) (err error) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
time.Sleep(dl.Sub(time.Now()))
|
||||
time.Sleep(time.Until(dl))
|
||||
c.kill()
|
||||
c.Stdout.Close()
|
||||
c.Stdin.Close()
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package optionaldeadline
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -54,7 +54,7 @@ func ContextWithOptionalDeadline(pctx context.Context) (ctx context.Context, enf
|
||||
}
|
||||
|
||||
// Deadline in past?
|
||||
sleepTime := deadline.Sub(time.Now())
|
||||
sleepTime := time.Until(deadline)
|
||||
if sleepTime <= 0 {
|
||||
rctx.m.Lock()
|
||||
rctx.err = context.DeadlineExceeded
|
||||
+27
-12
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package optionaldeadline
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zrepl/zrepl/util/chainlock"
|
||||
)
|
||||
|
||||
func TestContextWithOptionalDeadline(t *testing.T) {
|
||||
@@ -15,19 +17,28 @@ func TestContextWithOptionalDeadline(t *testing.T) {
|
||||
cctx, enforceDeadline := ContextWithOptionalDeadline(ctx)
|
||||
|
||||
begin := time.Now()
|
||||
var receivedCancellation time.Time
|
||||
var cancellationError error
|
||||
var checker struct {
|
||||
receivedCancellation time.Time
|
||||
cancellationError error
|
||||
timeout bool
|
||||
mtx chainlock.L
|
||||
}
|
||||
go func() {
|
||||
select {
|
||||
case <-cctx.Done():
|
||||
receivedCancellation = time.Now()
|
||||
cancellationError = cctx.Err()
|
||||
defer checker.mtx.Lock().Unlock()
|
||||
checker.receivedCancellation = time.Now()
|
||||
checker.cancellationError = cctx.Err()
|
||||
case <-time.After(600 * time.Millisecond):
|
||||
t.Fatalf("should have been cancelled by deadline")
|
||||
defer checker.mtx.Lock().Unlock()
|
||||
checker.timeout = true
|
||||
}
|
||||
}()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
if !receivedCancellation.IsZero() {
|
||||
defer checker.mtx.Lock().Unlock()
|
||||
checker.mtx.DropWhile(func() {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
})
|
||||
if !checker.receivedCancellation.IsZero() {
|
||||
t.Fatalf("no enforcement means no cancellation")
|
||||
}
|
||||
require.Nil(t, cctx.Err(), "no error while not cancelled")
|
||||
@@ -38,11 +49,15 @@ func TestContextWithOptionalDeadline(t *testing.T) {
|
||||
// second call must be ignored, i.e. we expect the deadline to be at begin+200ms, not begin+400ms
|
||||
enforceDeadline(begin.Add(400 * time.Millisecond))
|
||||
|
||||
time.Sleep(300 * time.Millisecond) // 100ms margin for scheduler
|
||||
if receivedCancellation.Sub(begin) > 250*time.Millisecond {
|
||||
t.Fatalf("cancellation is beyond acceptable scheduler latency")
|
||||
checker.mtx.DropWhile(func() {
|
||||
time.Sleep(300 * time.Millisecond) // 100ms margin for scheduler
|
||||
})
|
||||
assert.False(t, checker.timeout, "test timeout")
|
||||
receivedCancellationAfter := checker.receivedCancellation.Sub(begin)
|
||||
if receivedCancellationAfter > 250*time.Millisecond {
|
||||
t.Fatalf("cancellation is beyond acceptable scheduler latency: %s", receivedCancellationAfter)
|
||||
}
|
||||
require.Equal(t, context.DeadlineExceeded, cancellationError)
|
||||
require.Equal(t, context.DeadlineExceeded, checker.cancellationError)
|
||||
}
|
||||
|
||||
func TestContextWithOptionalDeadlineNegativeDeadline(t *testing.T) {
|
||||
Reference in New Issue
Block a user