platform: modularize api/gui, add docs-tests-web foundation, and refresh root config

This commit is contained in:
beckline
2026-03-26 22:40:54 +03:00
parent 0e2d7f61ea
commit 6a56d734c2
562 changed files with 70151 additions and 16423 deletions

View File

@@ -0,0 +1,78 @@
package app
import (
"net/http"
"sync"
"time"
)
const (
egressIdentityFreshTTL = 3 * time.Minute
egressIdentityBackoffMin = 3 * time.Second
egressIdentityBackoffMax = 2 * time.Minute
egressIdentityProbeTimeout = 4 * time.Second
egressIdentityGeoTimeout = 4 * time.Second
egressIdentityGeoCacheTTL = 24 * time.Hour
egressIdentityGeoFailTTL = 30 * time.Second
egressIdentityMaxConcurrency = 2
)
var (
egressIdentitySWR = newEgressIdentityService(
envInt("SVPN_EGRESS_MAX_PARALLEL", egressIdentityMaxConcurrency),
)
egressHTTPClient = &http.Client{}
)
type egressScopeTarget struct {
Scope string
Source string
SourceID string
}
type egressSourceProvider interface {
Probe(target egressScopeTarget) (string, error)
}
type egressIdentityEntry struct {
item EgressIdentity
swr refreshCoordinator
}
type egressGeoCacheEntry struct {
CountryCode string
CountryName string
LastError string
ExpiresAt time.Time
}
type egressIdentityService struct {
mu sync.Mutex
entries map[string]*egressIdentityEntry
sem chan struct{}
providers map[string]egressSourceProvider
geoMu sync.Mutex
geoCache map[string]egressGeoCacheEntry
}
type egressSystemProvider struct{}
type egressAdGuardProvider struct{}
type egressTransportProvider struct{}
func newEgressIdentityService(maxConcurrent int) *egressIdentityService {
n := maxConcurrent
if n <= 0 {
n = egressIdentityMaxConcurrency
}
return &egressIdentityService{
entries: map[string]*egressIdentityEntry{},
sem: make(chan struct{}, n),
providers: map[string]egressSourceProvider{
"system": egressSystemProvider{},
"adguardvpn": egressAdGuardProvider{},
"transport": egressTransportProvider{},
},
geoCache: map[string]egressGeoCacheEntry{},
}
}