mirror of
https://github.com/Xevion/vastly.git
synced 2025-12-05 23:16:48 -06:00
106 lines
2.0 KiB
Go
106 lines
2.0 KiB
Go
package api
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"time"
|
|
|
|
probing "github.com/prometheus-community/pro-bing"
|
|
"github.com/redis/go-redis/v9"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type LatencyRequest struct {
|
|
RequestTime int64
|
|
Ip net.IPAddr
|
|
}
|
|
|
|
type LatencyQueue struct {
|
|
processChannel chan LatencyRequest
|
|
stopChannel chan bool
|
|
logger *zap.SugaredLogger
|
|
redis *redis.Client
|
|
pinger *probing.Pinger
|
|
handlerChannel chan<- PingResult
|
|
}
|
|
|
|
func NewLatencyQueue() *LatencyQueue {
|
|
logger, _ := zap.NewDevelopment()
|
|
pinger, err := probing.NewPinger("127.0.0.1")
|
|
if err != nil {
|
|
logger.Fatal("Failed to create pinger")
|
|
}
|
|
pinger.Count = 1
|
|
pinger.Interval = time.Millisecond * 850
|
|
return &LatencyQueue{
|
|
processChannel: make(chan LatencyRequest, 1024),
|
|
logger: logger.Sugar(),
|
|
redis: redis.NewClient(&redis.Options{}),
|
|
pinger: pinger,
|
|
}
|
|
}
|
|
|
|
type PingRequest struct {
|
|
Ip net.IPAddr
|
|
}
|
|
|
|
type PingResult struct {
|
|
Ip net.IPAddr
|
|
Latency int64
|
|
}
|
|
|
|
func (l *LatencyQueue) QueuePing(ip string) error {
|
|
// Parse the IP
|
|
parsedIp := net.ParseIP(ip)
|
|
if parsedIp == nil {
|
|
return errors.New("Invalid IP address")
|
|
}
|
|
|
|
// Create the request
|
|
request := LatencyRequest{
|
|
RequestTime: time.Now().Unix(),
|
|
Ip: net.IPAddr{IP: parsedIp},
|
|
}
|
|
|
|
// Add the request to the queue
|
|
l.processChannel <- request
|
|
|
|
return nil
|
|
}
|
|
|
|
func (l *LatencyQueue) Start() {
|
|
for {
|
|
select {
|
|
case request := <-l.processChannel:
|
|
|
|
ip := request.Ip.String()
|
|
l.pinger.SetIPAddr(&request.Ip)
|
|
|
|
// Process the request
|
|
err := l.pinger.Run()
|
|
if err != nil {
|
|
l.logger.Errorf("Failed to ping %s: %s", ip, err)
|
|
continue
|
|
}
|
|
|
|
// Get the results
|
|
results := l.pinger.Statistics()
|
|
if (l.handlerChannel) != nil {
|
|
l.handlerChannel <- PingResult{
|
|
Ip: request.Ip,
|
|
Latency: results.AvgRtt.Milliseconds(),
|
|
}
|
|
}
|
|
|
|
case <-l.stopChannel:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (l *LatencyQueue) Kill() error {
|
|
l.stopChannel <- true
|
|
err := l.redis.Close()
|
|
return err
|
|
}
|