|
@@ -37,20 +37,21 @@ type (
|
|
|
state *State
|
|
|
waitGroup conc.WaitGroup
|
|
|
listeners []*listenerEntity
|
|
|
+ direct *Listener
|
|
|
exitFlag int32
|
|
|
}
|
|
|
)
|
|
|
|
|
|
func (gw *Gateway) handle(conn net.Conn) {
|
|
|
var (
|
|
|
- n int
|
|
|
- err error
|
|
|
- successed int32
|
|
|
- feature = make([]byte, minFeatureLength)
|
|
|
+ n int
|
|
|
+ err error
|
|
|
+ success int32
|
|
|
+ feature = make([]byte, minFeatureLength)
|
|
|
)
|
|
|
atomic.AddInt32(&gw.state.Concurrency, 1)
|
|
|
defer func() {
|
|
|
- if atomic.LoadInt32(&successed) != 1 {
|
|
|
+ if atomic.LoadInt32(&success) != 1 {
|
|
|
atomic.AddInt32(&gw.state.Concurrency, -1)
|
|
|
atomic.AddInt64(&gw.state.Request.Discarded, 1)
|
|
|
_ = conn.Close()
|
|
@@ -70,7 +71,7 @@ func (gw *Gateway) handle(conn net.Conn) {
|
|
|
}
|
|
|
for _, l := range gw.listeners {
|
|
|
if bytes.Compare(feature[:n], l.feature[:n]) == 0 {
|
|
|
- atomic.StoreInt32(&successed, 1)
|
|
|
+ atomic.StoreInt32(&success, 1)
|
|
|
l.listener.Receive(wrapConn(conn, gw.state, feature[:n]))
|
|
|
return
|
|
|
}
|
|
@@ -86,11 +87,16 @@ func (gw *Gateway) accept() {
|
|
|
if conn, err := gw.l.Accept(); err != nil {
|
|
|
break
|
|
|
} else {
|
|
|
- select {
|
|
|
- case gw.ch <- conn:
|
|
|
- atomic.AddInt64(&gw.state.Request.Total, 1)
|
|
|
- case <-gw.ctx.Done():
|
|
|
- return
|
|
|
+ //give direct listener
|
|
|
+ if gw.direct != nil {
|
|
|
+ gw.direct.Receive(conn)
|
|
|
+ } else {
|
|
|
+ select {
|
|
|
+ case gw.ch <- conn:
|
|
|
+ atomic.AddInt64(&gw.state.Request.Total, 1)
|
|
|
+ case <-gw.ctx.Done():
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -113,6 +119,12 @@ func (gw *Gateway) worker() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func (gw *Gateway) Direct(l net.Listener) {
|
|
|
+ if ls, ok := l.(*Listener); ok {
|
|
|
+ gw.direct = ls
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
func (gw *Gateway) Bind(feature Feature, listener net.Listener) (err error) {
|
|
|
var (
|
|
|
ok bool
|
|
@@ -165,7 +177,9 @@ func (gw *Gateway) Start(ctx context.Context) (err error) {
|
|
|
if gw.l, err = net.Listen("tcp", gw.address); err != nil {
|
|
|
return
|
|
|
}
|
|
|
- gw.waitGroup.Go(gw.worker)
|
|
|
+ for i := 0; i < 2; i++ {
|
|
|
+ gw.waitGroup.Go(gw.worker)
|
|
|
+ }
|
|
|
gw.waitGroup.Go(gw.accept)
|
|
|
return
|
|
|
}
|