mirror of
https://github.com/Gouryella/drip.git
synced 2026-02-23 21:00:44 +00:00
feat(protocol): Enhanced the heartbeat control mechanism of the frame writer
Added a heartbeatControl channel to support dynamic start/stop of the heartbeat function and optimized related resource management logic, ensuring that the heartbeat ticker can be correctly stopped and rebuilt. Also adjusted the field initialization order to ensure concurrency safety. fix(ui): Improved the tunnel connection status display style Updated the URL line display content, added the "(forwarded link)" prompt text; adjusted the style layout of the local forwarding address and prompt information, making the interface clearer and easier to read.
This commit is contained in:
@@ -21,6 +21,7 @@ type FrameWriter struct {
|
||||
heartbeatInterval time.Duration
|
||||
heartbeatCallback func() *Frame
|
||||
heartbeatEnabled bool
|
||||
heartbeatControl chan struct{}
|
||||
}
|
||||
|
||||
func NewFrameWriter(conn io.Writer) *FrameWriter {
|
||||
@@ -29,12 +30,13 @@ func NewFrameWriter(conn io.Writer) *FrameWriter {
|
||||
|
||||
func NewFrameWriterWithConfig(conn io.Writer, maxBatch int, maxBatchWait time.Duration, queueSize int) *FrameWriter {
|
||||
w := &FrameWriter{
|
||||
conn: conn,
|
||||
queue: make(chan *Frame, queueSize),
|
||||
batch: make([]*Frame, 0, maxBatch),
|
||||
maxBatch: maxBatch,
|
||||
maxBatchWait: maxBatchWait,
|
||||
done: make(chan struct{}),
|
||||
conn: conn,
|
||||
queue: make(chan *Frame, queueSize),
|
||||
batch: make([]*Frame, 0, maxBatch),
|
||||
maxBatch: maxBatch,
|
||||
maxBatchWait: maxBatchWait,
|
||||
done: make(chan struct{}),
|
||||
heartbeatControl: make(chan struct{}, 1),
|
||||
}
|
||||
go w.writeLoop()
|
||||
return w
|
||||
@@ -54,9 +56,11 @@ func (w *FrameWriter) writeLoop() {
|
||||
}
|
||||
w.mu.Unlock()
|
||||
|
||||
if heartbeatTicker != nil {
|
||||
defer heartbeatTicker.Stop()
|
||||
}
|
||||
defer func() {
|
||||
if heartbeatTicker != nil {
|
||||
heartbeatTicker.Stop()
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -93,6 +97,19 @@ func (w *FrameWriter) writeLoop() {
|
||||
}
|
||||
w.mu.Unlock()
|
||||
|
||||
case <-w.heartbeatControl:
|
||||
w.mu.Lock()
|
||||
if heartbeatTicker != nil {
|
||||
heartbeatTicker.Stop()
|
||||
heartbeatTicker = nil
|
||||
heartbeatCh = nil
|
||||
}
|
||||
if w.heartbeatEnabled && w.heartbeatInterval > 0 {
|
||||
heartbeatTicker = time.NewTicker(w.heartbeatInterval)
|
||||
heartbeatCh = heartbeatTicker.C
|
||||
}
|
||||
w.mu.Unlock()
|
||||
|
||||
case <-w.done:
|
||||
w.mu.Lock()
|
||||
w.flushBatchLocked()
|
||||
@@ -156,15 +173,27 @@ func (w *FrameWriter) Flush() {
|
||||
// EnableHeartbeat enables automatic heartbeat sending in the write loop.
|
||||
func (w *FrameWriter) EnableHeartbeat(interval time.Duration, callback func() *Frame) {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
w.heartbeatInterval = interval
|
||||
w.heartbeatCallback = callback
|
||||
w.heartbeatEnabled = true
|
||||
w.mu.Unlock()
|
||||
|
||||
select {
|
||||
case w.heartbeatControl <- struct{}{}:
|
||||
default:
|
||||
// Channel already has a pending signal, no need to send another
|
||||
}
|
||||
}
|
||||
|
||||
// DisableHeartbeat disables automatic heartbeat sending.
|
||||
func (w *FrameWriter) DisableHeartbeat() {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
w.heartbeatEnabled = false
|
||||
w.mu.Unlock()
|
||||
|
||||
select {
|
||||
case w.heartbeatControl <- struct{}{}:
|
||||
default:
|
||||
// Channel already has a pending signal, no need to send another
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user