~/Projects/mqtt-go
git clone https://code.lsong.org/mqtt-go
Commit
- Commit
- 7913e93fcf3bb085a0b5b1372ca56ec7665bcce8
- Author
- Mochi <[email protected]>
- Date
- 2019-10-23 21:05:37 +0100 +0100
- Diffstat
mqtt.go | 17 ++ parser.go | 3 parser_test.go | 3 processor.go | 108 ++++++++++++++++++ processor_test.go | 44 +++++++ processors/circ/buffer.go | 16 ++ processors/circ/buffer_test.go | 11 + processors/circ/reader.go | 34 +++++ processors/circ/writer.go | 11 + processors/ring/buffer.go | 199 --------------------------------- processors/ring/buffer_test.go | 214 ------------------------------------ processors/ring/ring.go | 1 processors/ring/ring_test.go | 1
Refactor, fixes to Circ Peek, start processor/parser
diff --git a/mqtt.go b/mqtt.go index 427e46cca321b0072c41ac5a59d093c653111f9d..aa4442e7bc0cd4ba4b6eb5ee8f5acc97382c74a4 100644 --- a/mqtt.go +++ b/mqtt.go @@ -12,6 +12,7 @@ "github.com/mochi-co/mqtt/auth" "github.com/mochi-co/mqtt/listeners" "github.com/mochi-co/mqtt/packets" + "github.com/mochi-co/mqtt/processors/circ" "github.com/mochi-co/mqtt/topics" "github.com/mochi-co/mqtt/topics/trie" ) @@ -90,8 +91,24 @@ // Serve begins the event loops for establishing client connections on all // attached listeners. func (s *Server) Serve() error { + s.listeners.ServeAll(s.EstablishConnection2) + "errors" + "bufio" +} + +// EstablishConnection establishes a new client connection with the broker. +func (s *Server) EstablishConnection2(lid string, c net.Conn, ac auth.Controller) error { + + p := NewProcessor(c, circ.NewReader(128), circ.NewWriter(128)) + + "net" "time" + fh := new(packets.FixedHeader) + err := p.ReadFixedHeader(fh) + if err != nil { + return ErrReadConnectFixedHeader + } return nil } diff --git a/parser.go b/parser.go index 8f5828209408d354c08daf35d0b1561bdbae1cf6..b021131029b0b7ccdc1aaae0d32ad0c4951ab3e2 100644 --- a/parser.go +++ b/parser.go @@ -5,6 +5,7 @@ "bufio" "encoding/binary" "errors" "io" + "log" "net" "sync" "time" @@ -66,6 +67,8 @@ peeked, err := p.R.Peek(1) if err != nil { return err } + + log.Println("Peeked", peeked) // Unpack message type and flags from byte 1. err = fh.Decode(peeked[0]) diff --git a/parser_test.go b/parser_test.go index 1bc65275fe558a6c7d62d53b0f3decdac0ddb1ce..6c5a3ce33616221744be2c98ed9cfbaaff4904ce 100644 --- a/parser_test.go +++ b/parser_test.go @@ -194,8 +194,9 @@ }, } */ - "github.com/mochi-co/mqtt/packets" + "net" + "bytes" conn := new(MockNetConn) // Test null data. diff --git a/processor.go b/processor.go new file mode 100644 index 0000000000000000000000000000000000000000..0e960fdbccdd29d6f0ac51a78110cf65e31e65c2 --- /dev/null +++ b/processor.go @@ -0,0 +1,108 @@ +package mqtt + +import ( + "encoding/binary" + "log" + "net" + "time" + + "github.com/mochi-co/mqtt/packets" + "github.com/mochi-co/mqtt/processors/circ" +) + +// Processor reads and writes bytes to a network connection. +type Processor struct { + + // Conn is the net.Conn used to establish the connection. + Conn net.Conn + + // R is a reader for reading incoming bytes. + R *circ.Reader + + // W is a writer for writing outgoing bytes. + W *circ.Writer + + // FixedHeader is the FixedHeader from the last read packet. + FixedHeader packets.FixedHeader +} + +// NewProcessor returns a new instance of Processor. +func NewProcessor(c net.Conn, r *circ.Reader, w *circ.Writer) *Processor { + return &Processor{ + Conn: c, + R: r, + W: w, + } +} + +// RefreshDeadline refreshes the read/write deadline for the net.Conn connection. +func (p *Processor) RefreshDeadline(keepalive uint16) { + if p.Conn != nil { + expiry := time.Duration(keepalive+(keepalive/2)) * time.Second + p.Conn.SetDeadline(time.Now().Add(expiry)) + } +} + +// ReadFixedHeader reads in the values of the next packet's fixed header. +func (p *Processor) ReadFixedHeader(fh *packets.FixedHeader) error { + + // Peek the maximum message type and flags, and length. + peeked, err := p.R.Peek(1) + if err != nil { + return err + } + + log.Println("Peeked", peeked) + + // Unpack message type and flags from byte 1. + err = fh.Decode(peeked[0]) + if err != nil { + + // @SPEC [MQTT-2.2.2-2] + // If invalid flags are received, the receiver MUST close the Network Connection. + return packets.ErrInvalidFlags + } + + log.Printf("FH %+v\n", fh) + + // The remaining length value can be up to 5 bytes. Peek through each byte + // looking for continue values, and if found increase the peek. Otherwise + // decode the bytes that were legit. + //p.fhBuffer = p.fhBuffer[:0] + buf := make([]byte, 0, 6) + i := 1 + //var b int64 = 2 + for b := int64(2); b < 6; b++ { + peeked, err = p.R.Peek(b) + if err != nil { + return err + } + + // Add the byte to the length bytes slice. + buf = append(buf, peeked[i]) + + // If it's not a continuation flag, end here. + if peeked[i] < 128 { + break + } + + // If i has reached 4 without a length terminator, throw a protocol violation. + i++ + if i == 4 { + return packets.ErrOversizedLengthIndicator + } + } + + // Calculate and store the remaining length. + rem, _ := binary.Uvarint(buf) + fh.Remaining = int(rem) + + // Discard the number of used length bytes + first byte. + //p.R.Discard(b) + + // Set the fixed header in the parser. + p.FixedHeader = *fh + + return nil + +} diff --git a/processor_test.go b/processor_test.go new file mode 100644 index 0000000000000000000000000000000000000000..b8c8e25745a18c68229b05a9893af893916ab712 --- /dev/null +++ b/processor_test.go @@ -0,0 +1,44 @@ +package mqtt + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/mochi-co/mqtt/packets" + "github.com/mochi-co/mqtt/processors/circ" +) + +func TestNewProcessor(t *testing.T) { + conn := new(MockNetConn) + p := NewProcessor(conn, circ.NewReader(16), circ.NewWriter(16)) + require.NotNil(t, p.R) +} + +func TestProcessorReadFixedHeader(t *testing.T) { + conn := new(MockNetConn) + + p := NewProcessor(conn, circ.NewReader(16), circ.NewWriter(16)) + + // Test null data. + fh := new(packets.FixedHeader) + //p.R.SetPos(0, 1) + fmt.Printf("A %+v\n", p.R) + err := p.ReadFixedHeader(fh) + require.Error(t, err) + + // Test insufficient peeking. + fh = new(packets.FixedHeader) + p.R.Set([]byte{packets.Connect << 4}, 0, 1) + p.R.SetPos(0, 1) + fmt.Printf("B %+v\n", p.R) + err = p.ReadFixedHeader(fh) + require.Error(t, err) + + fh = new(packets.FixedHeader) + p.R.Set([]byte{packets.Connect << 4, 0x00}, 0, 2) + p.R.SetPos(0, 2) + err = p.ReadFixedHeader(fh) + require.NoError(t, err) +} diff --git a/processors/circ/buffer.go b/processors/circ/buffer.go index 9bc4b20e267f1ada6e39332c302ea152f04e1ce7..2cd569d65cbd34376d5471d78f89e9b7c544294f 100644 --- a/processors/circ/buffer.go +++ b/processors/circ/buffer.go @@ -51,6 +51,22 @@ wcond: sync.NewCond(new(sync.Mutex)), } } +// Set writes bytes to a byte buffer. This method should only be used for testing +// and will panic if out of range. +func (b *buffer) Set(p []byte, start, end int) { + o := 0 + for i := start; i < end; i++ { + b.buf[i] = p[o] + o++ + } +} + +// SetPos sets the head and tail of the buffer. This method should only be +// used for testing. +func (b *buffer) SetPos(tail, head int64) { + b.tail, b.head = tail, head +} + // awaitCapacity will hold until there are n bytes free in the buffer, blocking // until there are at least n bytes to write without overrunning the tail. func (b *buffer) awaitCapacity(n int64) (head int64, err error) { diff --git a/processors/circ/buffer_test.go b/processors/circ/buffer_test.go index 5586854c37c3b06ac51512c17b34543d4cc2586f..43538e6e2e32558ba33582dd42e81954fcc67596 100644 --- a/processors/circ/buffer_test.go +++ b/processors/circ/buffer_test.go @@ -23,6 +23,17 @@ require.Equal(t, size, int64(len(buf.buf))) require.Equal(t, size, buf.size) } +func TestSet(t *testing.T) { + buf := newBuffer(8) + require.Equal(t, make([]byte, 4), buf.buf[0:4]) + p := []byte{'1', '2', '3', '4'} + buf.Set(p, 0, 4) + require.Equal(t, p, buf.buf[0:4]) + + buf.Set(p, 2, 6) + require.Equal(t, p, buf.buf[2:6]) +} + func TestAwaitCapacity(t *testing.T) { tests := []struct { tail int64 diff --git a/processors/circ/reader.go b/processors/circ/reader.go index 7fdb712654a5f70994b2e5aad702c46f22db348a..4bb649b0f845356e769a8f2987d2197fa6273726 100644 --- a/processors/circ/reader.go +++ b/processors/circ/reader.go @@ -71,6 +71,40 @@ tail := atomic.LoadInt64(&b.tail) head := atomic.LoadInt64(&b.head) // Wait until there's at least 1 byte of data. + /* + b.wcond.L.Lock() + for ; head == tail; head = atomic.LoadInt64(&b.head) { + if atomic.LoadInt64(&b.done) == 1 { + return nil, io.EOF + } + b.wcond.Wait() + } + b.wcond.L.Unlock() + */ + + // Figure out if we can get all n bytes. + if head == tail || head > tail && tail+n > head || head < tail && b.size-tail+head < n { + return nil, ErrInsufficientBytes + } + + // If we've wrapped, get the bytes from the next and start. + if head < tail { + b.tmp = b.buf[tail:b.size] + b.tmp = append(b.tmp, b.buf[:(tail+n)%b.size]...) + return b.tmp, nil + } else { + return b.buf[tail : tail+n], nil + } + + return nil, nil +} + +// PeekWait waits until their are n bytes available to return. +func (b *Reader) PeekWait(n int64) ([]byte, error) { + tail := atomic.LoadInt64(&b.tail) + head := atomic.LoadInt64(&b.head) + + // Wait until there's at least 1 byte of data. b.wcond.L.Lock() for ; head == tail; head = atomic.LoadInt64(&b.head) { if atomic.LoadInt64(&b.done) == 1 { diff --git a/processors/circ/writer.go b/processors/circ/writer.go index 90605afb70f5d7c3cfd8a2843701d2130f5fab46..9e6a00d0ee8587bb45a083b014fe016baba081af 100644 --- a/processors/circ/writer.go +++ b/processors/circ/writer.go @@ -55,7 +55,18 @@ return } //"fmt" + + //"fmt" package circ + if atomic.LoadInt64(&b.done) == 1 { + return 0, io.EOF + } + + // Wait until there's + _, err = b.awaitCapacity(int64(len(p))) + if err != nil { + return + } return } diff --git a/processors/ring/buffer.go b/processors/ring/buffer.go deleted file mode 100644 index d0f09649a4496d2ea3a1aed489f4e20abca6257b..0000000000000000000000000000000000000000 --- a/processors/ring/buffer.go +++ /dev/null @@ -1,199 +0,0 @@ -package ring - -import ( - "errors" - "fmt" - "io" - "sync" - "sync/atomic" -) - -var ( - blockSize int64 = 4 - - ErrInsufficientBytes = errors.New("Insufficient bytes to return") -) - -// _______________________________________________________________________ -// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -// ----------------------------------------------------------------------- - -// Buffer is a ring-style byte buffer. -type Buffer struct { - - // size is the size of the buffer. - size int64 - - // buffer is the circular byte buffer. - buffer []byte - - // tmp is a temporary buffer. - tmp []byte - - // head is the current position in the sequence. - head int64 - - // tail is the committed position in the sequence, I.E. where we - // have successfully consumed and processed to. - tail int64 - - // rcond is the sync condition for the reader. - rcond *sync.Cond - - // done indicates that the buffer is closed. - done int64 - - // wcond is the sync condition for the writer. - wcond *sync.Cond -} - -// NewBuffer returns a pointer to a new instance of Buffer. -func NewBuffer(size int64) *Buffer { - return &Buffer{ - size: size, - buffer: make([]byte, size), - tmp: make([]byte, size), - rcond: sync.NewCond(new(sync.Mutex)), - wcond: sync.NewCond(new(sync.Mutex)), - } -} - -// awaitCapacity will hold until there are n bytes free in the buffer. -// awaitCapacity will block until there are at least n bytes for the head to -// write into without overrunning the tail. -func (b *Buffer) awaitCapacity(n int64) (int64, error) { - tail := atomic.LoadInt64(&b.tail) - head := atomic.LoadInt64(&b.head) - next := head + n - wrapped := next - b.size - - b.rcond.L.Lock() - for ; wrapped > tail || (tail > head && next > tail && wrapped < 0); tail = atomic.LoadInt64(&b.tail) { - //fmt.Println("\t", wrapped, ">", tail, wrapped > tail, "||", tail, ">", head, "&&", next, ">", tail, "&&", wrapped, "<", 0, (tail > head && next > tail && wrapped < 0)) - b.rcond.Wait() - if atomic.LoadInt64(&b.done) == 1 { - fmt.Println("ending") - return 0, io.EOF - } - } - b.rcond.L.Unlock() - - return head, nil -} - -// ReadFrom reads bytes from an io.Reader and commits them to the buffer when -// there is sufficient capacity to do so. -func (b *Buffer) ReadFrom(r io.Reader) (total int64, err error) { -DONE: - for { - if atomic.LoadInt64(&b.done) == 1 { - err = io.EOF - break DONE - //return 0, io.EOF - } - - // Wait until there's enough capacity in the buffer. - st, err := b.awaitCapacity(blockSize) - if err != nil { - break DONE - //return 0, err - } - - // Find the start and end indexes within the buffer. - start := st & (b.size - 1) - end := start + blockSize - - // If we've overrun, just fill up to the end and then collect - // the rest on the next pass. - if end > b.size { - end = b.size - } - - // Read into the buffer between the start and end indexes only. - n, err := r.Read(b.buffer[start:end]) - total += int64(n) // incr total bytes read. - if err != nil { - break DONE - //return int64(n), err - } - - // Move the head forward. - //fmt.Println(start, end, b.buffer[start:end]) - // fmt.Println(">>", b.head, start+int64(n), end) - atomic.StoreInt64(&b.head, end) //start+int64(n)) - b.wcond.L.Lock() - b.wcond.Broadcast() - b.wcond.L.Unlock() - - } - - return -} - -// WriteTo writes the contents of the buffer to an io.Writer. -func (b *Buffer) WriteTo(w io.Writer) (total int64, err error) { - var p []byte - var n int -DONE: - for { - if atomic.LoadInt64(&b.done) == 1 { - err = io.EOF - break DONE - } - - // Peek until there's bytes to write. - p, err = b.Peek(blockSize) - if err != nil { - break DONE - } - - n, err = w.Write(p) - total += int64(n) - if err != nil { - break DONE - } - - // Move the tail forward the bytes written. - end := (atomic.LoadInt64(&b.tail) + int64(n)) % b.size - atomic.StoreInt64(&b.tail, end) - b.rcond.L.Lock() - b.rcond.Broadcast() - b.rcond.L.Unlock() - } - - return -} - -// Peek returns the next n bytes without advancing the reader. -func (b *Buffer) Peek(n int64) ([]byte, error) { - tail := atomic.LoadInt64(&b.tail) - head := atomic.LoadInt64(&b.head) - - // Wait until there's at least 1 byte of data. - b.wcond.L.Lock() - for ; head == tail; head = atomic.LoadInt64(&b.head) { - if atomic.LoadInt64(&b.done) == 1 { - return nil, io.EOF - } - b.wcond.Wait() - } - b.wcond.L.Unlock() - - // Figure out if we can get all n bytes. - start := tail - end := tail + n - if head > tail && tail+n > head || head < tail && b.size-tail+head < n { - return nil, ErrInsufficientBytes - } - - // If we've wrapped, get the bytes from the end and start. - if head < tail { - b.tmp = b.buffer[start:b.size] - b.tmp = append(b.tmp, b.buffer[:(end%b.size)]...) - return b.tmp, nil - } else { - return b.buffer[start:end], nil - } - - return nil, nil -} diff --git a/processors/ring/buffer_test.go b/processors/ring/buffer_test.go deleted file mode 100644 index 1bafd59bab47a71ee54dfcce434be72baf608b99..0000000000000000000000000000000000000000 --- a/processors/ring/buffer_test.go +++ /dev/null @@ -1,214 +0,0 @@ -package ring - -import ( - "bytes" - "fmt" - "io" - "io/ioutil" - "net" - "sync/atomic" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func init() { - blockSize = 4 -} - -func TestNewBuffer(t *testing.T) { - var size int64 = 256 - buf := NewBuffer(size) - - require.NotNil(t, buf.buffer) - require.Equal(t, size, int64(len(buf.buffer))) - require.Equal(t, size, buf.size) -} - -func TestAwaitCapacity(t *testing.T) { - tt := []struct { - tail int64 - head int64 - need int64 - await int - desc string - }{ - {0, 0, 4, 0, "OK 4, 0"}, - {6, 6, 4, 0, "OK 6, 10"}, - {12, 16, 4, 0, "OK 16, 4"}, - {16, 12, 4, 0, "OK 16 16"}, - {3, 6, 4, 0, "OK 3, 10"}, - {12, 0, 4, 0, "OK 16, 0"}, - {1, 16, 4, 4, "next is more than tail, wait for tail incr"}, - {7, 5, 4, 2, "tail is great than head, wrapped and caught up with tail, wait for tail incr"}, - } - - buf := NewBuffer(16) - for i, check := range tt { - buf.tail, buf.head = check.tail, check.head - o := make(chan []interface{}) - var start int64 = -1 - var err error - go func() { - start, err = buf.awaitCapacity(4) - o <- []interface{}{start, err} - }() - - time.Sleep(time.Millisecond) // atomic updates are super fast so wait a bit - for i := 0; i < check.await; i++ { - atomic.AddInt64(&buf.tail, 1) - buf.rcond.L.Lock() - buf.rcond.Broadcast() - buf.rcond.L.Unlock() - } - - time.Sleep(time.Millisecond) // wait for await capacity to actually exit - if start == -1 { - atomic.StoreInt64(&buf.done, 1) - buf.rcond.L.Lock() - buf.rcond.Broadcast() - buf.rcond.L.Unlock() - } - done := <-o - require.Equal(t, check.head, done[0].(int64), "Head-Start mismatch [i:%d] %s", i, check.desc) - require.Nil(t, done[1], "Unexpected Error [i:%d] %s", i, check.desc) - } -} - -func TestReadFrom(t *testing.T) { - buf := NewBuffer(16) - - b4 := bytes.Repeat([]byte{'-'}, 4) - br := bytes.NewReader(b4) - _, err := buf.ReadFrom(br) - require.NoError(t, err) - require.Equal(t, bytes.Repeat([]byte{'-'}, 4), buf.buffer[:4]) - require.Equal(t, int64(4), buf.head) - - br.Reset(b4) - _, err = buf.ReadFrom(br) - require.Equal(t, int64(8), buf.head) - - br.Reset(b4) - _, err = buf.ReadFrom(br) - require.Equal(t, int64(12), buf.head) - - br.Reset([]byte{'-', '-', '-', '-', '/', '/', '/', '/'}) - o := make(chan error) - go func() { - _, err := buf.ReadFrom(br) - o <- err - }() - - atomic.StoreInt64(&buf.tail, 4) - <-o - require.Equal(t, int64(4), buf.head) - require.Equal(t, []byte{'/', '/', '/', '/', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-'}, buf.buffer) -} - -func TestPeek(t *testing.T) { - - buf := NewBuffer(16) - buf.buffer = []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'} - - tests := []struct { - tail int64 - head int64 - want int - bytes []byte - err error - desc string - }{ - {tail: 0, head: 4, want: 4, bytes: []byte{'a', 'b', 'c', 'd'}, err: nil, desc: "0,4: OK"}, - {tail: 3, head: 15, want: 8, bytes: []byte{'d', 'e', 'f', 'g', 'h', 'i', 'j', 'k'}, err: nil, desc: "0,4: OK"}, - {tail: 14, head: 5, want: 6, bytes: []byte{'o', 'p', 'a', 'b', 'c', 'd'}, err: nil, desc: "14,5 OK"}, - {tail: 14, head: 1, want: 6, bytes: nil, err: ErrInsufficientBytes, desc: "14,1 insufficient bytes"}, - } - - for i, tt := range tests { - buf.tail, buf.head = tt.tail, tt.head - o := make(chan []interface{}) - go func() { - bs, err := buf.Peek(int64(tt.want)) - o <- []interface{}{bs, err} - }() - - time.Sleep(time.Millisecond) - atomic.StoreInt64(&buf.head, buf.head+int64(tt.want)) - time.Sleep(time.Millisecond * 10) - - buf.wcond.L.Lock() - buf.wcond.Broadcast() - buf.wcond.L.Unlock() - - time.Sleep(time.Millisecond) // wait for await capacity to actually exit - done := <-o - if tt.err != nil { - require.Error(t, done[1].(error), "Expected Error [i:%d] %s", i, tt.desc) - } else { - require.Nil(t, done[1], "Unexpected Error [i:%d] %s", i, tt.desc) - } - - require.Equal(t, tt.bytes, done[0].([]byte), "Peeked bytes mismatch [i:%d] %s", i, tt.desc) - } - - fmt.Println("done") - -} - -func TestWriteTo(t *testing.T) { - bb := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'} - - tests := []struct { - tail int64 - next int64 - head int64 - err error - bytes []byte - total int64 - desc string - }{ - {tail: 0, next: 4, head: 4, err: io.EOF, bytes: []byte{'a', 'b', 'c', 'd'}, total: 4, desc: "0, 4 OK"}, - {tail: 14, next: 2, head: 2, err: io.EOF, bytes: []byte{'o', 'p', 'a', 'b'}, total: 4, desc: "14, 2 wrap"}, - {tail: 0, next: 0, head: 2, err: ErrInsufficientBytes, bytes: []byte{}, total: 0, desc: "0, 2 insufficient"}, - {tail: 14, next: 2, head: 3, err: ErrInsufficientBytes, bytes: []byte{'o', 'p', 'a', 'b'}, total: 4, desc: "0, 3 OK > insufficient wrap"}, - } - - for i, tt := range tests { - buf := NewBuffer(16) - buf.buffer = bb - buf.tail, buf.head = tt.tail, tt.head - r, w := net.Pipe() - go func() { - time.Sleep(time.Millisecond) - atomic.StoreInt64(&buf.done, 1) - buf.wcond.L.Lock() - buf.wcond.Broadcast() - buf.wcond.L.Unlock() - w.Close() - }() - - recv := make(chan []byte) - go func() { - buf, err := ioutil.ReadAll(r) - if err != nil { - panic(err) - } - recv <- buf - }() - - total, err := buf.WriteTo(w) - require.Equal(t, tt.next, buf.tail, "Tail placement mismatched [i:%d] %s", i, tt.desc) - require.Equal(t, tt.total, total, "Total bytes written mismatch [i:%d] %s", i, tt.desc) - if tt.err != nil { - require.Error(t, err, "Expected Error [i:%d] %s", i, tt.desc) - } else { - require.NoError(t, err, "Unexpected Error [i:%d] %s", i, tt.desc) - } - require.Equal(t, tt.bytes, <-recv, "Written bytes mismatch [i:%d] %s", i, tt.desc) - - r.Close() - } - -} diff --git a/processors/ring/ring.go b/processors/ring/ring.go deleted file mode 100644 index e57875677865d99d3ba08debe9091731a3f0f318..0000000000000000000000000000000000000000 --- a/processors/ring/ring.go +++ /dev/null @@ -1 +0,0 @@ -package ring diff --git a/processors/ring/ring_test.go b/processors/ring/ring_test.go deleted file mode 100644 index e57875677865d99d3ba08debe9091731a3f0f318..0000000000000000000000000000000000000000 --- a/processors/ring/ring_test.go +++ /dev/null @@ -1 +0,0 @@ -package ring