first commit
This commit is contained in:
126
internal/continuous/tcping.go
Normal file
126
internal/continuous/tcping.go
Normal file
@@ -0,0 +1,126 @@
|
||||
package continuous
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type TCPingTask struct {
|
||||
TaskID string
|
||||
Target string
|
||||
Host string
|
||||
Port int
|
||||
Interval time.Duration
|
||||
MaxDuration time.Duration
|
||||
StartTime time.Time
|
||||
LastRequest time.Time
|
||||
StopCh chan struct{}
|
||||
IsRunning bool
|
||||
mu sync.RWMutex
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func NewTCPingTask(taskID, target string, interval, maxDuration time.Duration) (*TCPingTask, error) {
|
||||
// 解析host:port
|
||||
parts := strings.Split(target, ":")
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("无效的target格式,需要 host:port")
|
||||
}
|
||||
|
||||
host := parts[0]
|
||||
port, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("无效的端口: %v", err)
|
||||
}
|
||||
|
||||
logger, _ := zap.NewProduction()
|
||||
return &TCPingTask{
|
||||
TaskID: taskID,
|
||||
Target: target,
|
||||
Host: host,
|
||||
Port: port,
|
||||
Interval: interval,
|
||||
MaxDuration: maxDuration,
|
||||
StartTime: time.Now(),
|
||||
LastRequest: time.Now(),
|
||||
StopCh: make(chan struct{}),
|
||||
IsRunning: true,
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (t *TCPingTask) Start(ctx context.Context, resultCallback func(result map[string]interface{})) {
|
||||
ticker := time.NewTicker(t.Interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-t.StopCh:
|
||||
return
|
||||
case <-ticker.C:
|
||||
// 检查是否超过最大运行时长
|
||||
t.mu.RLock()
|
||||
if time.Since(t.StartTime) > t.MaxDuration {
|
||||
t.mu.RUnlock()
|
||||
t.Stop()
|
||||
return
|
||||
}
|
||||
t.mu.RUnlock()
|
||||
|
||||
// 执行tcping测试
|
||||
result := t.executeTCPing()
|
||||
if resultCallback != nil {
|
||||
resultCallback(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TCPingTask) Stop() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
if t.IsRunning {
|
||||
t.IsRunning = false
|
||||
close(t.StopCh)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TCPingTask) UpdateLastRequest() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.LastRequest = time.Now()
|
||||
}
|
||||
|
||||
func (t *TCPingTask) executeTCPing() map[string]interface{} {
|
||||
start := time.Now()
|
||||
conn, err := net.DialTimeout("tcp", net.JoinHostPort(t.Host, strconv.Itoa(t.Port)), 5*time.Second)
|
||||
latency := time.Since(start).Milliseconds()
|
||||
|
||||
if err != nil {
|
||||
return map[string]interface{}{
|
||||
"timestamp": time.Now().Unix(),
|
||||
"latency": -1,
|
||||
"success": false,
|
||||
"packet_loss": true,
|
||||
"error": err.Error(),
|
||||
}
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
return map[string]interface{}{
|
||||
"timestamp": time.Now().Unix(),
|
||||
"latency": float64(latency),
|
||||
"success": true,
|
||||
"packet_loss": false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user