diff --git a/config-example.yaml b/config-example.yaml index 9740f3ad..c32f9416 100644 --- a/config-example.yaml +++ b/config-example.yaml @@ -103,6 +103,12 @@ disable_check_updates: false # Time before an inactive ephemeral node is deleted? ephemeral_node_inactivity_timeout: 30m +# Period to check for changes in the tailnet. A value too low will severily affect +# CPU consumption of Headscale. A value too high (over 60s) will cause problems +# to the nodes, as they won't get updates or keep alive messages on time. +# In case of doubts, do not touch the default 10s. +changes_check_interval: 10s + # SQLite config db_type: sqlite3 db_path: /var/lib/headscale/db.sqlite diff --git a/config.go b/config.go index 9e71a750..0ef09110 100644 --- a/config.go +++ b/config.go @@ -26,6 +26,7 @@ type Config struct { GRPCAddr string GRPCAllowInsecure bool EphemeralNodeInactivityTimeout time.Duration + ChangesCheckInterval time.Duration IPPrefixes []netaddr.IPPrefix PrivateKeyPath string BaseDomain string @@ -162,6 +163,8 @@ func LoadConfig(path string, isFile bool) error { viper.SetDefault("ephemeral_node_inactivity_timeout", "120s") + viper.SetDefault("changes_check_interval", "10s") + if err := viper.ReadInConfig(); err != nil { log.Warn().Err(err).Msg("Failed to read configuration from disk") @@ -217,6 +220,15 @@ func LoadConfig(path string, isFile bool) error { ) } + maxChangesCheckInterval, _ := time.ParseDuration("60s") + if viper.GetDuration("changes_check_interval") > maxChangesCheckInterval { + errorText += fmt.Sprintf( + "Fatal config error: changes_check_interval (%s) is set too high, must be less than %s", + viper.GetString("changes_check_interval"), + maxChangesCheckInterval, + ) + } + if errorText != "" { //nolint return errors.New(strings.TrimSuffix(errorText, "\n")) @@ -478,6 +490,10 @@ func GetHeadscaleConfig() (*Config, error) { "ephemeral_node_inactivity_timeout", ), + ChangesCheckInterval: viper.GetDuration( + "changes_check_interval", + ), + DBtype: viper.GetString("db_type"), DBpath: AbsolutePathFromConfigPath(viper.GetString("db_path")), DBhost: viper.GetString("db_host"), diff --git a/poll.go b/poll.go index 9218495d..95fb542c 100644 --- a/poll.go +++ b/poll.go @@ -16,8 +16,7 @@ import ( ) const ( - keepAliveInterval = 60 * time.Second - updateCheckInterval = 10 * time.Second + keepAliveInterval = 60 * time.Second ) type contextKey string @@ -640,7 +639,7 @@ func (h *Headscale) scheduledPollWorker( machine *Machine, ) { keepAliveTicker := time.NewTicker(keepAliveInterval) - updateCheckerTicker := time.NewTicker(updateCheckInterval) + updateCheckerTicker := time.NewTicker(h.cfg.ChangesCheckInterval) defer closeChanWithLog( updateChan,