mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 09:16:57 +00:00
Rate limit fixes
This commit is contained in:
parent
7690b22c0a
commit
b382350f76
@ -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 {
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 ©
|
return ©
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user