platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
@@ -4,97 +4,35 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
eventsbuspkg "selective-vpn-api/app/eventsbus"
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// события / event bus
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// EN: In-memory bounded event bus used for SSE replay and polling watchers.
|
||||
// EN: It keeps only the latest N events and assigns monotonically increasing IDs.
|
||||
// RU: Ограниченная in-memory шина событий для SSE-реплея и фоновых вотчеров.
|
||||
// RU: Хранит только последние N событий и присваивает монотонно растущие ID.
|
||||
type eventBus struct {
|
||||
mu sync.Mutex
|
||||
cond *sync.Cond
|
||||
buf []Event
|
||||
cap int
|
||||
next int64
|
||||
inner *eventsbuspkg.Bus
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// EN: `newEventBus` creates a new instance for event bus.
|
||||
// RU: `newEventBus` - создает новый экземпляр для event bus.
|
||||
// ---------------------------------------------------------------------
|
||||
func newEventBus(capacity int) *eventBus {
|
||||
if capacity < 16 {
|
||||
capacity = 16
|
||||
}
|
||||
b := &eventBus{
|
||||
cap: capacity,
|
||||
buf: make([]Event, 0, capacity),
|
||||
}
|
||||
b.cond = sync.NewCond(&b.mu)
|
||||
return b
|
||||
return &eventBus{inner: eventsbuspkg.New(capacity)}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// EN: `push` contains core logic for push.
|
||||
// RU: `push` - содержит основную логику для push.
|
||||
// ---------------------------------------------------------------------
|
||||
func (b *eventBus) push(kind string, data interface{}) Event {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
b.next++
|
||||
evt := Event{
|
||||
ID: b.next,
|
||||
Kind: kind,
|
||||
Ts: time.Now().UTC().Format(time.RFC3339Nano),
|
||||
Data: data,
|
||||
}
|
||||
|
||||
if len(b.buf) >= b.cap {
|
||||
b.buf = b.buf[1:]
|
||||
}
|
||||
b.buf = append(b.buf, evt)
|
||||
b.cond.Broadcast()
|
||||
return evt
|
||||
ev := b.inner.Push(kind, data)
|
||||
return Event{ID: ev.ID, Kind: ev.Kind, Ts: ev.Ts, Data: ev.Data}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// EN: `since` contains core logic for since.
|
||||
// RU: `since` - содержит основную логику для since.
|
||||
// ---------------------------------------------------------------------
|
||||
func (b *eventBus) since(id int64) []Event {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
return b.sinceLocked(id)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// EN: `sinceLocked` contains core logic for since locked.
|
||||
// RU: `sinceLocked` - содержит основную логику для since locked.
|
||||
// ---------------------------------------------------------------------
|
||||
func (b *eventBus) sinceLocked(id int64) []Event {
|
||||
if len(b.buf) == 0 {
|
||||
raw := b.inner.Since(id)
|
||||
if len(raw) == 0 {
|
||||
return nil
|
||||
}
|
||||
var out []Event
|
||||
for _, ev := range b.buf {
|
||||
if ev.ID > id {
|
||||
out = append(out, ev)
|
||||
}
|
||||
out := make([]Event, 0, len(raw))
|
||||
for _, ev := range raw {
|
||||
out = append(out, Event{ID: ev.ID, Kind: ev.Kind, Ts: ev.Ts, Data: ev.Data})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// env helpers
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// EN: Positive integer env reader with safe default fallback.
|
||||
// RU: Чтение положительного целого из env с безопасным fallback на дефолт.
|
||||
func envInt(key string, def int) int {
|
||||
|
||||
Reference in New Issue
Block a user