func (c *connector) SetAttr(key string, value interface{}) {
	c.Lock()
	c.attrs[key] = value
	c.Unlock()
}
SetAttr add a attr on session
package goetty
import (
	"errors"
	"net"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)
var (
	ErrWrite = errors.New("goetty.net: Write failed")
	ErrEmptyServers = errors.New("goetty.Connector: Empty servers pool")
	ErrIllegalState = errors.New("goetty.Connector: Not connected")
)
type Conf struct {
	Addr                   string
	TimeoutConnectToServer time.Duration
	TimeWheel              *TimeoutWheel
	TimeoutWrite           time.Duration
	WriteTimeoutFn         func(string, IOSession)
}
type connector struct {
	sync.RWMutex
	cnf   *Conf
	attrs map[string]interface{}
	lastTimeout Timeout
	conn         net.Conn
	decoder      Decoder
	encoder      Encoder
	in           *ByteBuf
	out          *ByteBuf
	closed       int32
	writeBufSize int
	batchLimit uint64
	batchCount uint64
}
func NewConnector(cnf *Conf, decoder Decoder, encoder Encoder) IOSession {
	return NewConnectorSize(cnf, decoder, encoder, BufReadSize, BufWriteSize)
}
func NewConnectorSize(cnf *Conf, decoder Decoder, encoder Encoder, readBufSize, writeBufSize int) IOSession {
	return &connector{
		cnf:          cnf,
		in:           NewByteBuf(readBufSize),
		out:          NewByteBuf(writeBufSize),
		writeBufSize: writeBufSize,
		decoder:      decoder,
		encoder:      encoder,
		attrs:        make(map[string]interface{}),
	}
}
func (c *connector) InBuf() *ByteBuf {
	return c.in
}
func (c *connector) OutBuf() *ByteBuf {
	return c.out
}
func (c *connector) WriteOutBuf() error {
	buf := c.out
	c.batchCount = 0
	written := 0
	all := buf.Readable()
	for {
		if written == all {
			break
		}
		n, err := c.conn.Write(buf.buf[buf.readerIndex+written : buf.writerIndex])
		if err != nil {
			c.writeRelease()
			return err
		}
		written += n
	}
	c.writeRelease()
	return nil
}