в процессе, нет аккордиона, нет графика

This commit is contained in:
Tot Maxim
2026-05-07 23:12:21 +03:00
parent 9c28b9501d
commit 0bdab22a34
9 changed files with 287 additions and 167 deletions

View File

@@ -2,6 +2,7 @@ package adapter
import (
"sync"
"sync/atomic"
"time"
)
@@ -11,29 +12,39 @@ type RingBuffer struct {
writePtr int
count int
lastWrite time.Time
lastWrite atomic.Int64
// ===== SPEED METRICS =====
totalBytes uint64
totalBytes atomic.Uint64
lastTick time.Time
lastBytes uint64
bytesPerSec float64
bitsPerSec float64
// ===== SPEED =====
lastTick atomic.Int64
lastBytes atomic.Uint64
bytesPerSec atomic.Value // float64
bitsPerSec atomic.Value // float64
}
// =====================
func NewRingBuffer(size int) *RingBuffer {
return &RingBuffer{
data: make([]byte, size),
lastWrite: time.Now(),
lastTick: time.Now(),
rb := &RingBuffer{
data: make([]byte, size),
}
now := time.Now().UnixNano()
rb.lastWrite.Store(now)
rb.lastTick.Store(now)
rb.bytesPerSec.Store(float64(0))
rb.bitsPerSec.Store(float64(0))
return rb
}
// =====================
func (rb *RingBuffer) Write(b byte) {
rb.mu.Lock()
// ===== WRITE =====
rb.data[rb.writePtr] = b
rb.writePtr = (rb.writePtr + 1) % len(rb.data)
@@ -41,40 +52,45 @@ func (rb *RingBuffer) Write(b byte) {
rb.count++
}
rb.lastWrite = time.Now()
rb.totalBytes++
rb.mu.Unlock()
// ===== SPEED CALC (outside lock) =====
now := rb.lastWrite
// ===== ATOMIC STATS =====
now := time.Now().UnixNano()
rb.lastWrite.Store(now)
if rb.lastTick.IsZero() {
rb.lastTick = now
rb.lastBytes = rb.totalBytes
total := rb.totalBytes.Add(1)
// ===== SPEED CALC =====
lastTick := rb.lastTick.Load()
if lastTick == 0 {
rb.lastTick.Store(now)
rb.lastBytes.Store(total)
return
}
elapsed := now.Sub(rb.lastTick).Seconds()
if elapsed >= 1.0 {
diff := rb.totalBytes - rb.lastBytes
rb.bytesPerSec = float64(diff) / elapsed
rb.bitsPerSec = rb.bytesPerSec * 8
rb.lastTick = now
rb.lastBytes = rb.totalBytes
elapsed := time.Duration(now - lastTick).Seconds()
if elapsed < 1.0 {
return
}
last := rb.lastBytes.Load()
diff := total - last
bps := float64(diff) / elapsed
rb.bytesPerSec.Store(bps)
rb.bitsPerSec.Store(bps * 8)
rb.lastTick.Store(now)
rb.lastBytes.Store(total)
}
// =====================
func (rb *RingBuffer) LastWriteTime() time.Time {
rb.mu.RLock()
defer rb.mu.RUnlock()
return rb.lastWrite
return time.Unix(0, rb.lastWrite.Load())
}
// =====================
func (rb *RingBuffer) GetLatest() (byte, bool) {
rb.mu.RLock()
defer rb.mu.RUnlock()
@@ -91,6 +107,7 @@ func (rb *RingBuffer) GetLatest() (byte, bool) {
return rb.data[idx], true
}
// =====================
func (rb *RingBuffer) GetLast(n int) []byte {
rb.mu.RLock()
defer rb.mu.RUnlock()
@@ -105,7 +122,6 @@ func (rb *RingBuffer) GetLast(n int) []byte {
if start < 0 {
start += len(rb.data)
copy(res, rb.data[start:])
copy(res[len(rb.data)-start:], rb.data[:rb.writePtr])
} else {
@@ -115,26 +131,32 @@ func (rb *RingBuffer) GetLast(n int) []byte {
return res
}
// =====================
func (rb *RingBuffer) IsAlive(timeout time.Duration) bool {
rb.mu.RLock()
defer rb.mu.RUnlock()
return time.Since(rb.lastWrite) < timeout
return time.Since(time.Unix(0, rb.lastWrite.Load())) < timeout
}
// =====================
func (rb *RingBuffer) Stats() map[string]interface{} {
rb.mu.RLock()
defer rb.mu.RUnlock()
filled := rb.count
rb.mu.RUnlock()
bps, _ := rb.bytesPerSec.Load().(float64)
bits, _ := rb.bitsPerSec.Load().(float64)
total := rb.totalBytes.Load()
return map[string]interface{}{
"size": len(rb.data),
"filled": rb.count,
"last_write": rb.lastWrite,
"size": len(rb.data),
"filled": filled,
"total_bytes": rb.totalBytes,
"total_bits": rb.totalBytes * 8,
"last_write": time.Unix(0, rb.lastWrite.Load()),
"bytes_per_sec": rb.bytesPerSec,
"bits_per_sec": rb.bitsPerSec,
"total_bytes": total,
"total_bits": total * 8,
"bytes_per_sec": bps,
"bits_per_sec": bits,
}
}