func (c *client) String() string {
	return fmt.Sprintf("RegionClient{Addr: %s}", c.addr)
}
String returns a string represintation of the current region client
package region
import (
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"github.com/prometheus/client_golang/prometheus"
	log "github.com/sirupsen/logrus"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/codes"
	"github.com/tsuna/gohbase/hrpc"
	"github.com/tsuna/gohbase/internal/observability"
	"github.com/tsuna/gohbase/pb"
	"google.golang.org/protobuf/encoding/protowire"
	"google.golang.org/protobuf/proto"
)
type ClientType string
type canDeserializeCellBlocks interface {
	DeserializeCellBlocks(proto.Message, []byte) (uint32, error)
}
type canSerializeCellBlocks interface {
	SerializeCellBlocks() (proto.Message, [][]byte, uint32)
	CellBlocksEnabled() bool
}
var (
	ErrMissingCallID = ServerError{errors.New("got a response with a nonsensical call ID")}
	ErrClientClosed = ServerError{errors.New("client is closed")}
	javaRegionExceptions = map[string]string{
		"org.apache.hadoop.hbase.NotServingRegionException":       "",
		"org.apache.hadoop.hbase.exceptions.RegionMovedException": "",
		"java.io.IOException": "Cannot append; log is closed",
	}
	javaRetryableExceptions = map[string]string{
		"org.apache.hadoop.hbase.CallQueueTooBigException":          "",
		"org.apache.hadoop.hbase.exceptions.RegionOpeningException": "",
		"org.apache.hadoop.hbase.ipc.ServerNotRunningYetException":  "",
		"org.apache.hadoop.hbase.quotas.RpcThrottlingException":     "",
		"org.apache.hadoop.hbase.RetryImmediatelyException":         "",
		"org.apache.hadoop.hbase.RegionTooBusyException":            "",
	}
	javaServerExceptions = map[string]string{
		"org.apache.hadoop.hbase.regionserver.RegionServerAbortedException": "",
		"org.apache.hadoop.hbase.regionserver.RegionServerStoppedException": "",
	}
)
const (
	DefaultLookupTimeout = 30 * time.Second
	DefaultReadTimeout = 30 * time.Second
	RegionClient = ClientType("ClientService")
	MasterClient = ClientType("MasterService")
)
var bufferPool = sync.Pool{
	New: func() interface{} {
		var b []byte
		return b
	},
}
func newBuffer(size int) []byte {
	b := bufferPool.Get().([]byte)
	if cap(b) < size {
		doublecap := 2 * cap(b)
		if doublecap > size {
			return make([]byte, size, doublecap)
		}
		return make([]byte, size)
	}
	return b[:size]
}
func freeBuffer(b []byte) {
	bufferPool.Put(b[:0])  
}
type ServerError struct {
	error
}
func formatErr(e interface{}, err error) string {
	if err == nil {
		return fmt.Sprintf("%T", e)
	}
	return fmt.Sprintf("%T: %s", e, err.Error())
}
func (e ServerError) Error() string {
	return formatErr(e, e.error)
}
type RetryableError struct {
	error
}
func (e RetryableError) Error() string {
	return formatErr(e, e.error)
}
type NotServingRegionError struct {
	error
}
func (e NotServingRegionError) Error() string {
	return formatErr(e, e.error)
}
type client struct {
	conn net.Conn
	addr  string
	ctype ClientType
	dialOnce sync.Once
	failOnce sync.Once
	rpcs chan hrpc.Call
	done chan struct{}
	sentM sync.Mutex  
	sent  map[uint32]hrpc.Call
	inFlightM sync.Mutex  
	inFlight  uint32
	id uint32
	rpcQueueSize  int
	flushInterval time.Duration
	effectiveUser string
	readTimeout time.Duration
	compressor *compressor
}
func (c *client) QueueRPC(rpc hrpc.Call) {
	if b, ok := rpc.(hrpc.Batchable); ok && c.rpcQueueSize > 1 && !b.SkipBatch() {
		select {
		case <-rpc.Context().Done():
		case <-c.done:
			returnResult(rpc, nil, ErrClientClosed)
		case c.rpcs <- rpc:
		}
	} else {
		if err := c.trySend(rpc); err != nil {
			returnResult(rpc, nil, err)
		}
	}
}
func (c *client) Close() {
	c.fail(ErrClientClosed)
}
func (c *client) Addr() string {
	return c.addr
}