cont: model encodings
This commit is contained in:
parent
1014ac6fd5
commit
e2c8a92089
|
@ -14,13 +14,14 @@ type Encoder struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
subctx context.Context
|
subctx context.Context
|
||||||
mux sync.Mutex
|
mux sync.Mutex
|
||||||
out io.WriteCloser
|
//out io.WriteCloser
|
||||||
|
out io.Writer
|
||||||
outErr chan error
|
outErr chan error
|
||||||
bufferSize int
|
bufferSize int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEncoder returns an Encoder instance
|
// NewEncoder returns an Encoder instance
|
||||||
func NewEncoder(ctx context.Context, wout io.WriteCloser) *Encoder {
|
func NewEncoder(ctx context.Context, wout io.Writer) *Encoder {
|
||||||
enc := &Encoder{
|
enc := &Encoder{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
out: wout,
|
out: wout,
|
||||||
|
@ -44,7 +45,7 @@ func (enc *Encoder) Run() error {
|
||||||
// TODO: do children respond to children cancelling?
|
// TODO: do children respond to children cancelling?
|
||||||
case <-enc.ctx.Done():
|
case <-enc.ctx.Done():
|
||||||
// TODO
|
// TODO
|
||||||
_ = enc.out.Close()
|
//_ = enc.out.Close()
|
||||||
return errors.New("context cancelled")
|
return errors.New("context cancelled")
|
||||||
case err := <-enc.outErr:
|
case err := <-enc.outErr:
|
||||||
// if a write fails for one, it fail for all
|
// if a write fails for one, it fail for all
|
||||||
|
@ -53,14 +54,8 @@ func (enc *Encoder) Run() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start will Run() the encoder in a goroutine
|
|
||||||
func (enc *Encoder) Start() error {
|
|
||||||
go enc.Run()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode adds MPLEXY headers to raw net traffic, and is intended to be used on each client connection
|
// Encode adds MPLEXY headers to raw net traffic, and is intended to be used on each client connection
|
||||||
func (enc *Encoder) Encode(rin io.ReadCloser, src Addr) error {
|
func (enc *Encoder) Encode(rin io.Reader, src Addr) error {
|
||||||
rx := make(chan []byte)
|
rx := make(chan []byte)
|
||||||
rxErr := make(chan error)
|
rxErr := make(chan error)
|
||||||
|
|
||||||
|
@ -86,25 +81,25 @@ func (enc *Encoder) Encode(rin io.ReadCloser, src Addr) error {
|
||||||
// would it be sufficient to expect the reader to be closed by the caller instead?
|
// would it be sufficient to expect the reader to be closed by the caller instead?
|
||||||
case <-enc.ctx.Done():
|
case <-enc.ctx.Done():
|
||||||
// TODO: verify that closing the reader will cause the goroutine to be released
|
// TODO: verify that closing the reader will cause the goroutine to be released
|
||||||
rin.Close()
|
//rin.Close()
|
||||||
return errors.New("cancelled by context")
|
return errors.New("cancelled by context")
|
||||||
case <-enc.subctx.Done():
|
case <-enc.subctx.Done():
|
||||||
rin.Close()
|
//rin.Close()
|
||||||
return errors.New("cancelled by context")
|
return errors.New("cancelled by context")
|
||||||
case b := <-rx:
|
case b := <-rx:
|
||||||
header, _, err := Encode(src, Addr{}, "", b)
|
header, _, err := Encode(src, Addr{}, "", b)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
rin.Close()
|
//rin.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
_, err = enc.write(header, b)
|
_, err = enc.write(header, b)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
rin.Close()
|
//rin.Close()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case err := <-rxErr:
|
case err := <-rxErr:
|
||||||
// it can be assumed that err will close though, right?
|
// it can be assumed that err will close though, right?
|
||||||
rin.Close()
|
//rin.Close()
|
||||||
if io.EOF == err {
|
if io.EOF == err {
|
||||||
header, _, _ := Encode(src, Addr{scheme: "end"}, "", nil)
|
header, _, _ := Encode(src, Addr{scheme: "end"}, "", nil)
|
||||||
// ignore err, which may have already closed
|
// ignore err, which may have already closed
|
||||||
|
|
|
@ -3,6 +3,7 @@ package packer
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -45,14 +46,15 @@ func TestEncodeWholeBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ctx := context.Background()
|
// TODO nix context here
|
||||||
|
ctx := context.TODO()
|
||||||
rin, wout := net.Pipe()
|
rin, wout := net.Pipe()
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
b := make([]byte, 1024)
|
b := make([]byte, 1024)
|
||||||
n, err := rin.Read(b)
|
n, err := rin.Read(b)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Printf("Error: %s\n", err)
|
t.Fatalf("Error: %s\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r := b[:n]
|
r := b[:n]
|
||||||
|
@ -60,8 +62,18 @@ func TestEncodeWholeBlock(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
encoder := NewEncoder(ctx, wout)
|
encoder := NewEncoder(ctx, wout)
|
||||||
encoder.Start()
|
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
err := encoder.Run()
|
||||||
|
if nil != err {
|
||||||
|
if io.EOF != err {
|
||||||
|
t.Fatalf("Encoder Run Err: %q\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wout.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// TODO eliminate Run and don't sleep here
|
||||||
time.Sleep(time.Millisecond)
|
time.Sleep(time.Millisecond)
|
||||||
|
|
||||||
// single client
|
// single client
|
||||||
|
@ -79,7 +91,7 @@ func TestEncodeWholeBlock(t *testing.T) {
|
||||||
port: 4834,
|
port: 4834,
|
||||||
})
|
})
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Printf("Enc Err: %q\n", err)
|
t.Fatalf("Enc Err 1: %q\n", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -98,11 +110,11 @@ func TestEncodeWholeBlock(t *testing.T) {
|
||||||
port: 4834,
|
port: 4834,
|
||||||
})
|
})
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Printf("Enc Err 2: %q\n", err)
|
t.Fatalf("Enc Err 2: %q\n", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// TODO must be a better way to do this
|
// TODO use wait group
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
|
|
Loading…
Reference in New Issue