fix: 仅向已握手连接推送并拆分调度循环

This commit is contained in:
Nixevol
2026-09-30 16:22:43 +08:00
parent ad4f13193c
commit 83521f4b87
14 changed files with 1192 additions and 290 deletions
+133
View File
@@ -0,0 +1,133 @@
package message
import (
"context"
"git.asio.asia/nixevol/NixMsg/internal/app/port"
)
type pushWorker struct {
endpointID string
connID port.ConnID
wake chan struct{}
stop chan struct{}
done chan struct{}
}
func (a *App) startPushWorker(endpointID string, connID port.ConnID) {
a.stopPushWorker(endpointID, "")
w := &pushWorker{
endpointID: endpointID,
connID: connID,
wake: make(chan struct{}, 1),
stop: make(chan struct{}),
done: make(chan struct{}),
}
a.mu.Lock()
a.workers[endpointID] = w
a.mu.Unlock()
go a.runPushWorker(w)
}
func (a *App) stopPushWorker(endpointID string, connID port.ConnID) {
a.mu.Lock()
w, ok := a.workers[endpointID]
if !ok || (connID != "" && w.connID != connID) {
a.mu.Unlock()
return
}
delete(a.workers, endpointID)
a.mu.Unlock()
close(w.stop)
<-w.done
}
func (a *App) runPushWorker(w *pushWorker) {
defer close(w.done)
for {
select {
case <-w.stop:
return
case <-w.wake:
ctx, cancel := context.WithTimeout(context.Background(), pushOpTimeout)
_ = a.PushPending(ctx, w.endpointID, w.connID)
a.flushRevokes(ctx)
cancel()
}
}
}
func (a *App) signalWorker(endpointID string) {
a.mu.Lock()
w := a.workers[endpointID]
a.mu.Unlock()
if w == nil {
return
}
select {
case w.wake <- struct{}{}:
default:
}
}
func (a *App) markHandshook(endpointID string, conn LiveConn) {
conn.Ready = true
a.mu.Lock()
a.handshook[endpointID] = conn.ConnID
a.mu.Unlock()
if setter, ok := a.conns.(interface {
Set(string, LiveConn)
}); ok {
setter.Set(endpointID, conn)
}
}
func (a *App) clearHandshook(endpointID string, connID port.ConnID) {
a.mu.Lock()
defer a.mu.Unlock()
if cur, ok := a.handshook[endpointID]; ok && (connID == "" || cur == connID) {
delete(a.handshook, endpointID)
}
}
func (a *App) canPush(endpointID string, connID port.ConnID) (LiveConn, port.ConnID, bool) {
live, ok := a.lookupConn(endpointID)
if !ok {
return LiveConn{}, "", false
}
if connID != "" && live.ConnID != connID {
return LiveConn{}, "", false
}
if connID == "" {
connID = live.ConnID
}
if live.Ready {
return live, connID, true
}
a.mu.Lock()
hs, marked := a.handshook[endpointID]
a.mu.Unlock()
if marked && hs == live.ConnID {
return live, connID, true
}
return LiveConn{}, "", false
}
func (a *App) isReadyEndpoint(endpointID string) bool {
_, _, ok := a.canPush(endpointID, "")
return ok
}
func shortWriteCtx() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), clearPushedTimeout)
}
func (a *App) NotifyDispatch() {
if a.dispatchCh == nil {
return
}
select {
case a.dispatchCh <- struct{}{}:
default:
}
}