func HandleMalloc(f func(int) []byte) {
	DefaultHandler.HandleMalloc(f)
}
HandleMalloc registers default buffer maker.
package arpc
import (
	"bufio"
	"context"
	"fmt"
	"io"
	"net"
	"github.com/lesismal/arpc/codec"
	"github.com/lesismal/arpc/log"
	"github.com/lesismal/arpc/util"
)
var DefaultHandler Handler = NewHandler()
type HandlerFunc func(*Context)
type routerHandler struct {
	async    bool
	handlers []HandlerFunc
}
type Handler interface {
	Clone() Handler
	LogTag() string
	SetLogTag(tag string)
	HandleConnected(onConnected func(*Client))
	OnConnected(c *Client)
	HandleDisconnected(onDisConnected func(*Client))
	OnDisconnected(c *Client)
	MaxReconnectTimes() int
	SetMaxReconnectTimes(n int)
	HandleOverstock(onOverstock func(c *Client, m *Message))
	OnOverstock(c *Client, m *Message)
	HandleMessageDone(onMessageDone func(c *Client, m *Message))
	OnMessageDone(c *Client, m *Message)
	HandleMessageDropped(onOverstock func(c *Client, m *Message))
	OnMessageDropped(c *Client, m *Message)
	HandleSessionMiss(onSessionMiss func(c *Client, m *Message))
	OnSessionMiss(c *Client, m *Message)
	HandleContextDone(onContextDone func(ctx *Context))
	OnContextDone(ctx *Context)
	BeforeRecv(h func(net.Conn) error)
	BeforeSend(h func(net.Conn) error)
	BatchRecv() bool
	SetBatchRecv(batch bool)
	BatchSend() bool
	SetBatchSend(batch bool)
	AsyncWrite() bool
	SetAsyncWrite(async bool)
	AsyncResponse() bool
	SetAsyncResponse(async bool)
	WrapReader(conn net.Conn) io.Reader
	SetReaderWrapper(wrapper func(conn net.Conn) io.Reader)
	Recv(c *Client) (*Message, error)
	Send(c net.Conn, buffer []byte) (int, error)
	SendN(conn net.Conn, buffers net.Buffers) (int, error)
	RecvBufferSize() int
	SetRecvBufferSize(size int)
	SendBufferSize() int
	SetSendBufferSize(size int)
	SendQueueSize() int
	SetSendQueueSize(size int)
	MaxBodyLen() int
	SetMaxBodyLen(l int)
	Use(h HandlerFunc)
	UseCoder(coder MessageCoder)
	Coders() []MessageCoder
	Handle(m string, h HandlerFunc, args ...interface{})
	HandleNotFound(h HandlerFunc)
	OnMessage(c *Client, m *Message)
	Malloc(size int) []byte
	HandleMalloc(f func(size int) []byte)
	Free([]byte)
	HandleFree(f func(buf []byte))
	EnablePool(enable bool)
	Context() (context.Context, context.CancelFunc)
	SetContext(ctx context.Context, cancel context.CancelFunc)
	Cancel()
	NewMessage(cmd byte, method string, v interface{}, isError bool, isAsync bool, seq uint64, codec codec.Codec, values map[interface{}]interface{}) *Message
	NewMessageWithBuffer(buffer []byte) *Message
	SetAsyncExecutor(executor func(f func()))
	AsyncExecute(f func())
}
type handler struct {
	logtag            string
	batchRecv         bool
	batchSend         bool
	asyncWrite        bool
	asyncResponse     bool
	recvBufferSize    int
	sendBufferSize    int
	sendQueueSize     int
	maxBodyLen        int
	maxReconnectTimes int
	onConnected      func(*Client)
	onDisConnected   func(*Client)
	onOverstock      func(c *Client, m *Message)
	onMessageDone    func(c *Client, m *Message)
	onMessageDropped func(c *Client, m *Message)
	onSessionMiss    func(c *Client, m *Message)
	onContextDone    func(ctx *Context)
	beforeRecv func(net.Conn) error
	beforeSend func(net.Conn) error
	malloc     func(int) []byte
	free       func([]byte)
	wrapReader func(conn net.Conn) io.Reader
	middles   []HandlerFunc
	msgCoders []MessageCoder
	routes map[string]*routerHandler
	ctx    context.Context
	cancel context.CancelFunc
	executor func(f func())
}
func (h *handler) Clone() Handler {
	cp := *h
	cp.middles = make([]HandlerFunc, len(h.middles))
	copy(cp.middles, h.middles)
	cp.msgCoders = make([]MessageCoder, len(h.msgCoders))
	copy(cp.msgCoders, h.msgCoders)
	cp.routes = map[string]*routerHandler{}
	for k, v := range h.routes {
		rh := &routerHandler{
			async:    v.async,
			handlers: make([]HandlerFunc, len(v.handlers)),
		}
		copy(rh.handlers, v.handlers)
		cp.routes[k] = rh
	}
	ctx, cancel := context.WithCancel(context.Background())
	cp.ctx = ctx
	cp.cancel = cancel
	return &cp
}
func (h *handler) LogTag() string {
	return h.logtag
}
func (h *handler) SetLogTag(tag string) {
	h.logtag = tag
}
func (h *handler) HandleConnected(onConnected func(*Client)) {
	if onConnected == nil {
		return
	}
	pre := h.onConnected
	h.onConnected = func(c *Client) {
		if pre != nil {
			pre(c)
		}
		onConnected(c)
	}
}
func (h *handler) OnConnected(c *Client) {
	if h.onConnected != nil {
		h.onConnected(c)
	}
}
func (h *handler) HandleDisconnected(onDisConnected func(*Client)) {
	if onDisConnected == nil {
		return
	}
	pre := h.onDisConnected
	h.onDisConnected = func(c *Client) {
		if pre != nil {
			pre(c)
		}
		onDisConnected(c)
	}
}
func (h *handler) OnDisconnected(c *Client) {
	if h.onDisConnected != nil {
		h.onDisConnected(c)
	}
}
func (h *handler) MaxReconnectTimes() int {
	return h.maxReconnectTimes
}
func (h *handler) SetMaxReconnectTimes(n int) {
	h.maxReconnectTimes = n
}
func (h *handler) HandleOverstock(onOverstock func(c *Client, m *Message)) {
	h.onOverstock = func(c *Client, m *Message) {
		onOverstock(c, m)
		h.OnMessageDone(c, m)
	}
}
func (h *handler) OnOverstock(c *Client, m *Message) {
	if h.onOverstock != nil {
		h.onOverstock(c, m)
	}
}
func (h *handler) HandleMessageDropped(onMessageDropped func(c *Client, m *Message)) {
	h.onMessageDropped = func(c *Client, m *Message) {
		onMessageDropped(c, m)
		h.OnMessageDone(c, m)
	}
}
func (h *handler) OnMessageDropped(c *Client, m *Message) {
	if h.onMessageDropped != nil {
		h.onMessageDropped(c, m)
	}
}
func (h *handler) HandleMessageDone(onMessageDone func(c *Client, m *Message)) {
	h.onMessageDone = onMessageDone
}
func (h *handler) OnMessageDone(c *Client, m *Message) {
	if h.onMessageDone != nil && m != nil {
		h.onMessageDone(c, m)
	}
}
func (h *handler) HandleSessionMiss(onSessionMiss func(c *Client, m *Message)) {
	h.onSessionMiss = onSessionMiss
}
func (h *handler) OnSessionMiss(c *Client, m *Message) {
	if h.onSessionMiss != nil {
		h.onSessionMiss(c, m)
		h.OnMessageDone(c, m)
	}
}
func (h *handler) HandleContextDone(onContextDone func(ctx *Context)) {
	h.onContextDone = onContextDone
}
func (h *handler) OnContextDone(ctx *Context) {
	if h.onContextDone != nil {
		h.onContextDone(ctx)
	}
}
func (h *handler) BeforeRecv(hb func(net.Conn) error) {
	h.beforeRecv = hb
}
func (h *handler) BeforeSend(hs func(net.Conn) error) {
	h.beforeSend = hs
}
func (h *handler) BatchRecv() bool {
	return h.batchRecv
}
func (h *handler) SetBatchRecv(batch bool) {
	h.batchRecv = batch
}
func (h *handler) BatchSend() bool {
	return h.batchSend
}
func (h *handler) SetBatchSend(batch bool) {
	h.batchSend = batch
}
func (h *handler) AsyncWrite() bool {
	return h.asyncWrite
}
func (h *handler) SetAsyncWrite(async bool) {
	h.asyncWrite = async
}
func (h *handler) AsyncResponse() bool {
	return h.asyncResponse
}
func (h *handler) SetAsyncResponse(async bool) {
	h.asyncResponse = async
}
func (h *handler) WrapReader(conn net.Conn) io.Reader {
	if h.wrapReader != nil {
		return h.wrapReader(conn)
	}
	return conn
}
func (h *handler) SetReaderWrapper(wrapper func(conn net.Conn) io.Reader) {
	h.wrapReader = wrapper
}
func (h *handler) RecvBufferSize() int {
	return h.recvBufferSize
}
func (h *handler) SetRecvBufferSize(size int) {
	h.recvBufferSize = size
}
func (h *handler) SendBufferSize() int {
	return h.sendBufferSize
}
func (h *handler) SetSendBufferSize(size int) {
	h.sendBufferSize = size
}
func (h *handler) SendQueueSize() int {
	return h.sendQueueSize
}
func (h *handler) SetSendQueueSize(size int) {
	h.sendQueueSize = size
}
func (h *handler) MaxBodyLen() int {
	return h.maxBodyLen
}
func (h *handler) SetMaxBodyLen(l int) {
	h.maxBodyLen = l
}
func (h *handler) Use(cb HandlerFunc) {
	if cb == nil {
		return
	}
	cbWithNext := func(ctx *Context) {
		cb(ctx)
		ctx.Next()
	}
	h.middles = append(h.middles, cbWithNext)
	for k, v := range h.routes {
		rh := &routerHandler{
			async:    v.async,
			handlers: make([]HandlerFunc, len(v.handlers)+1),
		}
		copy(rh.handlers, v.handlers)
		rh.handlers[len(v.handlers)] = cbWithNext
		h.routes[k] = rh
	}
}
func (h *handler) UseCoder(coder MessageCoder) {
	if coder != nil {
		h.msgCoders = append(h.msgCoders, coder)
	}
}
func (h *handler) Coders() []MessageCoder {
	return h.msgCoders
}
func (h *handler) Handle(method string, cb HandlerFunc, args ...interface{}) {
	if method == "" {
		panic(fmt.Errorf("empty('') method is reserved for [method not found], should use HandleNotFound to register '' handler"))
	}
	h.handle(method, cb, args...)
}
func (h *handler) HandleNotFound(cb HandlerFunc) {
	h.handle("", cb)
}
func (h *handler) handle(method string, cb HandlerFunc, args ...interface{}) {
	if h.routes == nil {
		h.routes = map[string]*routerHandler{}
	}
	if len(method) > MaxMethodLen {
		panic(fmt.Errorf("invalid method length %v(> MaxMethodLen %v)", len(method), MaxMethodLen))
	}
	if _, ok := h.routes[""]; !ok {
		rh := &routerHandler{
			async:    false,
			handlers: make([]HandlerFunc, len(h.middles)+1),
		}
		copy(rh.handlers, h.middles)
		rh.handlers[len(h.middles)] = func(ctx *Context) {
			ctx.Error(ErrMethodNotFound)
			ctx.Next()
		}
		h.routes[""] = rh
	}
	if _, ok := h.routes[method]; ok && method != "" {
		panic(fmt.Errorf("handler exist for method %v ", method))
	}
	async := h.AsyncResponse()
	if len(args) > 0 {
		if bv, ok := args[0].(bool); ok {
			async = bv
		}
	}
	rh := &routerHandler{
		async:    async,
		handlers: make([]HandlerFunc, len(h.middles)+1),
	}
	copy(rh.handlers, h.middles)
	rh.handlers[len(h.middles)] = func(ctx *Context) {
		cb(ctx)
		ctx.Next()
	}
	h.routes[method] = rh
}
func (h *handler) Recv(c *Client) (*Message, error) {
	var (
		err     error
		message *Message
	)
	if h.beforeRecv != nil {
		if err = h.beforeRecv(c.Conn); err != nil {
			return nil, err
		}
	}
	_, err = io.ReadFull(c.Reader, c.Head[:])
	if err != nil {
		return nil, err
	}
	message, err = c.Head.message(h)
	if err != nil {
		return nil, err
	}
	if message.Len() > HeadLen {
		_, err = io.ReadFull(c.Reader, message.Buffer[HeaderIndexBodyLenEnd:])
	}
	return message, err
}
func (h *handler) Send(conn net.Conn, buffer []byte) (int, error) {
	if h.beforeSend != nil {
		if err := h.beforeSend(conn); err != nil {
			return -1, err
		}
	}
	n, err := conn.Write(buffer)
	return n, err
}
func (h *handler) SendN(conn net.Conn, buffers net.Buffers) (int, error) {
	if h.beforeSend != nil {
		if err := h.beforeSend(conn); err != nil {
			return -1, err
		}
	}
	n64, err := buffers.WriteTo(conn)
	return int(n64), err
}
func (h *handler) OnMessage(c *Client, msg *Message) {
	defer util.Recover()
	for i := len(h.msgCoders) - 1; i >= 0; i-- {
		msg = h.msgCoders[i].Decode(c, msg)
	}
	ml := msg.MethodLen()
	if ml <= 0 || ml > MaxMethodLen || ml > (msg.Len()-HeadLen) {
		log.Warn("%v OnMessage: invalid request method length %v, dropped", h.LogTag(), ml)
		return
	}
	cmd := msg.Cmd()
	switch cmd {
	case CmdRequest, CmdNotify:
		method := msg.method()
		if rh, ok := h.routes[method]; ok {
			ctx := newContext(c, msg, rh.handlers)
			if !rh.async {
				ctx.Next()
				h.OnContextDone(ctx)
			} else {
				h.AsyncExecute(func() {
					ctx.Next()
					h.OnContextDone(ctx)
				})
			}
		} else {
			if cmd == CmdRequest {
				if rh, ok = h.routes[""]; ok {
					ctx := newContext(c, msg, rh.handlers)
					ctx.Next()
					h.OnContextDone(ctx)
					return
				}
			}
			ctx := newContext(c, msg, rh.handlers)
			ctx.Error(ErrMethodNotFound)
			h.OnContextDone(ctx)
			log.Warn("%v OnMessage: invalid method: [%v], no handler", h.LogTag(), method)
		}
	case CmdResponse:
		if !msg.IsAsync() {
			seq := msg.Seq()
			session, ok := c.getSession(seq)
			if ok {
				session.done <- msg
			} else {
				h.OnSessionMiss(c, msg)
				log.Warn("%v OnMessage: session not exist or expired", h.LogTag())
			}
		} else {
			handler, ok := c.getAndDeleteAsyncHandler(msg.Seq())
			if ok {
				ctx := newContext(c, msg, nil)
				handler(ctx)
				h.OnContextDone(ctx)
			} else {
				h.OnSessionMiss(c, msg)
				log.Warn("%v OnMessage: async handler not exist or expired", h.LogTag())
			}
		}
	default:
		log.Warn("%v OnMessage: invalid cmd [%v]", h.LogTag(), msg.Cmd())
	}
}
func (h *handler) Malloc(size int) []byte {
	if h.malloc != nil {
		return h.malloc(size)
	}
	return make([]byte, size)
}
func (h *handler) HandleMalloc(f func(int) []byte) {
	h.malloc = f
}
func (h *handler) Free(b []byte) {
	if h.free != nil {
		h.free(b)
	}
}
func (h *handler) HandleFree(f func([]byte)) {
	h.free = f
}
func (h *handler) EnablePool(enable bool) {
	if enable {
		h.HandleMalloc(func(size int) []byte {
			return BufferPool.Malloc(size)
		})
		h.HandleFree(func(buf []byte) {
			BufferPool.Free(buf)
		})
		h.HandleContextDone(func(ctx *Context) {
			ctx.Release()
		})
		h.HandleMessageDone(func(c *Client, m *Message) {
			m.Release()
		})
	} else {
		h.HandleMalloc(func(size int) []byte {
			return make([]byte, size)
		})
		h.HandleFree(func(buf []byte) {})
		h.HandleContextDone(func(ctx *Context) {})
		h.HandleMessageDone(func(c *Client, m *Message) {})
	}
}
func (h *handler) Context() (context.Context, context.CancelFunc) {
	return h.ctx, h.cancel
}
func (h *handler) SetContext(ctx context.Context, cancel context.CancelFunc) {
	h.ctx = ctx
	h.cancel = cancel
}
func (h *handler) Cancel() {
	if h.cancel != nil {
		h.cancel()
	}
}
func (h *handler) NewMessage(cmd byte, method string, v interface{}, isError bool, isAsync bool, seq uint64, codec codec.Codec, values map[interface{}]interface{}) *Message {
	return newMessage(cmd, method, v, false, false, seq, h, codec, values)
}
func (h *handler) NewMessageWithBuffer(buffer []byte) *Message {
	msg := messagePool.Get().(*Message)
	msg.Buffer = buffer
	msg.handler = h
	return msg
}
func (h *handler) SetAsyncExecutor(executor func(f func())) {
	h.executor = executor
}
func (h *handler) AsyncExecute(f func()) {
	if h.executor != nil {
		h.executor(f)
	} else {
		go util.Safe(f)
	}
}
func NewHandler() Handler {
	h := &handler{
		logtag:         "[ARPC CLI]",
		batchRecv:      true,
		batchSend:      true,
		asyncWrite:     true,
		asyncResponse:  false,
		recvBufferSize: 8192,
		sendQueueSize:  4096,
		maxBodyLen:     DefaultMaxBodyLen,
	}
	h.wrapReader = func(conn net.Conn) io.Reader {
		return bufio.NewReaderSize(conn, h.recvBufferSize)
	}
	ctx, cancel := context.WithCancel(context.Background())
	h.ctx = ctx
	h.cancel = cancel
	return h
}
func SetHandler(h Handler) {
	DefaultHandler = h
}
func SetLogTag(tag string) {
	DefaultHandler.SetLogTag(tag)
}
func HandleConnected(onConnected func(*Client)) {
	DefaultHandler.HandleConnected(onConnected)
}
func HandleDisconnected(onDisConnected func(*Client)) {
	DefaultHandler.HandleDisconnected(onDisConnected)
}
func HandleOverstock(onOverstock func(c *Client, m *Message)) {
	DefaultHandler.HandleOverstock(onOverstock)
}
func HandleMessageDropped(onOverstock func(c *Client, m *Message)) {
	DefaultHandler.HandleMessageDropped(onOverstock)
}
func HandleSessionMiss(onSessionMiss func(c *Client, m *Message)) {
	DefaultHandler.HandleSessionMiss(onSessionMiss)
}
func BeforeRecv(h func(net.Conn) error) {
	DefaultHandler.BeforeRecv(h)
}
func BeforeSend(h func(net.Conn) error) {
	DefaultHandler.BeforeSend(h)
}
func BatchRecv() bool {
	return DefaultHandler.BatchRecv()
}
func SetBatchRecv(batch bool) {
	DefaultHandler.SetBatchRecv(batch)
}
func BatchSend() bool {
	return DefaultHandler.BatchSend()
}
func SetBatchSend(batch bool) {
	DefaultHandler.SetBatchSend(batch)
}
func AsyncResponse() bool {
	return DefaultHandler.AsyncResponse()
}
func SetAsyncResponse(async bool) {
	DefaultHandler.SetAsyncResponse(async)
}
func SetReaderWrapper(wrapper func(conn net.Conn) io.Reader) {
	DefaultHandler.SetReaderWrapper(wrapper)
}
func RecvBufferSize() int {
	return DefaultHandler.RecvBufferSize()
}
func SetRecvBufferSize(size int) {
	DefaultHandler.SetRecvBufferSize(size)
}
func SendBufferSize() int {
	return DefaultHandler.SendBufferSize()
}
func SetSendBufferSize(size int) {
	DefaultHandler.SetSendBufferSize(size)
}
func SendQueueSize() int {
	return DefaultHandler.SendQueueSize()
}
func SetSendQueueSize(size int) {
	DefaultHandler.SetSendQueueSize(size)
}
func MaxBodyLen() int {
	return DefaultHandler.MaxBodyLen()
}
func SetMaxBodyLen(l int) {
	DefaultHandler.SetMaxBodyLen(l)
}
func Use(h HandlerFunc) {
	DefaultHandler.Use(h)
}
func UseCoder(coder MessageCoder) {
	DefaultHandler.UseCoder(coder)
}
func Handle(m string, h HandlerFunc, args ...interface{}) {
	DefaultHandler.Handle(m, h, args...)
}
func HandleNotFound(h HandlerFunc) {
	DefaultHandler.HandleNotFound(h)
}