You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.2 KiB
Go
143 lines
3.2 KiB
Go
package tao
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"hash/fnv"
|
|
"os"
|
|
"reflect"
|
|
"runtime"
|
|
"time"
|
|
"unsafe"
|
|
)
|
|
|
|
// ErrUndefined for undefined message type.
|
|
type ErrUndefined int32
|
|
|
|
func (e ErrUndefined) Error() string {
|
|
return fmt.Sprintf("undefined message type %d", e)
|
|
}
|
|
|
|
// Error codes returned by failures dealing with server or connection.
|
|
var (
|
|
ErrParameter = errors.New("parameter error")
|
|
ErrNilKey = errors.New("nil key")
|
|
ErrNilValue = errors.New("nil value")
|
|
ErrWouldBlock = errors.New("would block")
|
|
ErrNotHashable = errors.New("not hashable")
|
|
ErrNilData = errors.New("nil data")
|
|
ErrBadData = errors.New("more than 8M data")
|
|
ErrNotRegistered = errors.New("handler not registered")
|
|
ErrServerClosed = errors.New("server has been closed")
|
|
)
|
|
|
|
// definitions about some constants.
|
|
const (
|
|
MaxConnections = 1000
|
|
BufferSize128 = 128
|
|
BufferSize256 = 256
|
|
BufferSize512 = 512
|
|
BufferSize1024 = 1024
|
|
defaultWorkersNum = 20
|
|
)
|
|
|
|
type onConnectFunc func(WriteCloser) bool
|
|
type onMessageFunc func(Message, WriteCloser)
|
|
type onCloseFunc func(WriteCloser)
|
|
type onErrorFunc func(WriteCloser)
|
|
|
|
type workerFunc func()
|
|
type onScheduleFunc func(time.Time, WriteCloser)
|
|
|
|
// OnTimeOut represents a timed task.
|
|
type OnTimeOut struct {
|
|
Callback func(time.Time, WriteCloser)
|
|
Ctx context.Context
|
|
}
|
|
|
|
// NewOnTimeOut returns OnTimeOut.
|
|
func NewOnTimeOut(ctx context.Context, cb func(time.Time, WriteCloser)) *OnTimeOut {
|
|
return &OnTimeOut{
|
|
Callback: cb,
|
|
Ctx: ctx,
|
|
}
|
|
}
|
|
|
|
// Hashable is a interface for hashable object.
|
|
type Hashable interface {
|
|
HashCode() int32
|
|
}
|
|
|
|
const intSize = unsafe.Sizeof(1)
|
|
|
|
func hashCode(k interface{}) uint32 {
|
|
var code uint32
|
|
h := fnv.New32a()
|
|
switch v := k.(type) {
|
|
case bool:
|
|
h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case int:
|
|
h.Write((*((*[intSize]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case int8:
|
|
h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case int16:
|
|
h.Write((*((*[2]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case int32:
|
|
h.Write((*((*[4]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case int64:
|
|
h.Write((*((*[8]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case uint:
|
|
h.Write((*((*[intSize]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case uint8:
|
|
h.Write((*((*[1]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case uint16:
|
|
h.Write((*((*[2]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case uint32:
|
|
h.Write((*((*[4]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case uint64:
|
|
h.Write((*((*[8]byte)(unsafe.Pointer(&v))))[:])
|
|
code = h.Sum32()
|
|
case string:
|
|
h.Write([]byte(v))
|
|
code = h.Sum32()
|
|
case Hashable:
|
|
c := v.HashCode()
|
|
h.Write((*((*[4]byte)(unsafe.Pointer(&c))))[:])
|
|
code = h.Sum32()
|
|
default:
|
|
panic("key not hashable")
|
|
}
|
|
return code
|
|
}
|
|
|
|
func isNil(v interface{}) bool {
|
|
if v == nil {
|
|
return true
|
|
}
|
|
rv := reflect.ValueOf(v)
|
|
kd := rv.Type().Kind()
|
|
switch kd {
|
|
case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
|
|
return rv.IsNil()
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func printStack() {
|
|
var buf [4096]byte
|
|
n := runtime.Stack(buf[:], false)
|
|
os.Stderr.Write(buf[:n])
|
|
}
|