Rate limit fixes

This commit is contained in:
anonpenguin23 2026-02-06 11:09:34 +02:00
parent 7690b22c0a
commit b382350f76
7 changed files with 44 additions and 24 deletions

View File

@ -618,6 +618,18 @@ func (o *Orchestrator) restartServices() error {
// Get services to restart // Get services to restart
services := utils.GetProductionServices() services := utils.GetProductionServices()
// Re-enable namespace services BEFORE restarting debros-node.
// orama prod stop disables them, and debros-node's PartOf= dependency
// won't propagate restart to disabled services. We must re-enable first
// so that namespace gateways restart with the updated binary.
for _, svc := range services {
if strings.Contains(svc, "@") {
if err := exec.Command("systemctl", "enable", svc).Run(); err != nil {
fmt.Printf(" ⚠️ Warning: Failed to re-enable %s: %v\n", svc, err)
}
}
}
// If this is a nameserver, also restart CoreDNS and Caddy // If this is a nameserver, also restart CoreDNS and Caddy
if o.setup.IsNameserver() { if o.setup.IsNameserver() {
nameserverServices := []string{"coredns", "caddy"} nameserverServices := []string{"coredns", "caddy"}
@ -672,7 +684,7 @@ func (o *Orchestrator) restartServices() error {
} }
} }
// Start any remaining services not in priority list // Start any remaining services not in priority list (includes namespace services)
for _, svc := range services { for _, svc := range services {
found := false found := false
for _, priority := range priorityOrder { for _, priority := range priorityOrder {

View File

@ -174,20 +174,27 @@ func GetProductionServices() []string {
} }
} }
// Also discover namespace-specific services (debros-*@<namespace>.service) // Discover namespace service instances from the namespaces data directory.
// These are created when namespaces are provisioned and need to be restarted too // We can't rely on scanning /etc/systemd/system because that only contains
systemdDir := "/etc/systemd/system" // template files (e.g. debros-namespace-gateway@.service) with no instance name.
entries, err := os.ReadDir(systemdDir) // Restarting a template without an instance is a no-op.
// Instead, scan the data directory where each subdirectory is a provisioned namespace.
namespacesDir := "/home/debros/.orama/data/namespaces"
nsEntries, err := os.ReadDir(namespacesDir)
if err == nil { if err == nil {
for _, entry := range entries { serviceTypes := []string{"rqlite", "olric", "gateway"}
name := entry.Name() for _, nsEntry := range nsEntries {
// Look for debros-*@*.service pattern (namespace services) if !nsEntry.IsDir() {
if strings.HasPrefix(name, "debros-") && continue
strings.Contains(name, "@") && }
strings.HasSuffix(name, ".service") { ns := nsEntry.Name()
// Extract service name without .service extension for _, svcType := range serviceTypes {
serviceName := strings.TrimSuffix(name, ".service") // Only add if the env file exists (service was provisioned)
existing = append(existing, serviceName) envFile := filepath.Join(namespacesDir, ns, svcType+".env")
if _, err := os.Stat(envFile); err == nil {
svcName := fmt.Sprintf("debros-namespace-%s@%s", svcType, ns)
existing = append(existing, svcName)
}
} }
} }
} }

View File

@ -224,12 +224,14 @@ func (d *DatabaseClientImpl) connectToAvailableNode() (*gorqlite.Connection, err
var conn *gorqlite.Connection var conn *gorqlite.Connection
var err error var err error
// Disable gorqlite cluster discovery to avoid /nodes timeouts from unreachable peers // Disable gorqlite cluster discovery to avoid /nodes timeouts from unreachable peers.
// Use level=none to read from local SQLite directly (no leader forwarding).
// Writes are unaffected — they always go through Raft consensus.
openURL := rqliteURL openURL := rqliteURL
if strings.Contains(openURL, "?") { if strings.Contains(openURL, "?") {
openURL += "&disableClusterDiscovery=true" openURL += "&disableClusterDiscovery=true&level=none"
} else { } else {
openURL += "?disableClusterDiscovery=true" openURL += "?disableClusterDiscovery=true&level=none"
} }
conn, err = gorqlite.Open(openURL) conn, err = gorqlite.Open(openURL)
if err != nil { if err != nil {

View File

@ -128,9 +128,9 @@ func initializeRQLite(logger *logging.ColoredLogger, cfg *Config, deps *Dependen
} }
if strings.Contains(dsn, "?") { if strings.Contains(dsn, "?") {
dsn += "&disableClusterDiscovery=true" dsn += "&disableClusterDiscovery=true&level=none"
} else { } else {
dsn += "?disableClusterDiscovery=true" dsn += "?disableClusterDiscovery=true&level=none"
} }
db, err := sql.Open("rqlite", dsn) db, err := sql.Open("rqlite", dsn)
if err != nil { if err != nil {

View File

@ -310,8 +310,8 @@ func New(logger *logging.ColoredLogger, cfg *Config) (*Gateway, error) {
// Initialize request log batcher (flush every 5 seconds) // Initialize request log batcher (flush every 5 seconds)
gw.logBatcher = newRequestLogBatcher(gw, 5*time.Second, 100) gw.logBatcher = newRequestLogBatcher(gw, 5*time.Second, 100)
// Initialize rate limiter (300 req/min, burst 50) // Initialize rate limiter (10000 req/min, burst 5000)
gw.rateLimiter = NewRateLimiter(300, 50) gw.rateLimiter = NewRateLimiter(10000, 5000)
gw.rateLimiter.StartCleanup(5*time.Minute, 10*time.Minute) gw.rateLimiter.StartCleanup(5*time.Minute, 10*time.Minute)
// Initialize WireGuard peer exchange handler // Initialize WireGuard peer exchange handler

View File

@ -17,7 +17,7 @@ type RQLiteAdapter struct {
// NewRQLiteAdapter creates a new adapter that provides sql.DB interface for RQLite // NewRQLiteAdapter creates a new adapter that provides sql.DB interface for RQLite
func NewRQLiteAdapter(manager *RQLiteManager) (*RQLiteAdapter, error) { func NewRQLiteAdapter(manager *RQLiteManager) (*RQLiteAdapter, error) {
// Use the gorqlite database/sql driver // Use the gorqlite database/sql driver
db, err := sql.Open("rqlite", fmt.Sprintf("http://localhost:%d?disableClusterDiscovery=true", manager.config.RQLitePort)) db, err := sql.Open("rqlite", fmt.Sprintf("http://localhost:%d?disableClusterDiscovery=true&level=none", manager.config.RQLitePort))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open RQLite SQL connection: %w", err) return nil, fmt.Errorf("failed to open RQLite SQL connection: %w", err)
} }

View File

@ -62,7 +62,7 @@ func DefaultConfig() *Config {
DefaultRetryDelaySeconds: 5, DefaultRetryDelaySeconds: 5,
// Rate limiting // Rate limiting
GlobalRateLimitPerMinute: 10000, // 10k requests/minute globally GlobalRateLimitPerMinute: 250000, // 250k requests/minute globally
// Background jobs // Background jobs
JobWorkers: 4, JobWorkers: 4,
@ -184,4 +184,3 @@ func (c *Config) WithRateLimit(perMinute int) *Config {
copy.GlobalRateLimitPerMinute = perMinute copy.GlobalRateLimitPerMinute = perMinute
return &copy return &copy
} }