From 46e30753447290706eb733fd74f13a9067bd8ab9 Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Wed, 15 Jan 2014 12:17:40 -1000 Subject: [PATCH] Adding AEConfig and some methods to scale timing --- command/agent/config.go | 7 +++++++ command/agent/util.go | 25 +++++++++++++++++++++++++ command/agent/util_test.go | 22 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 command/agent/util.go create mode 100644 command/agent/util_test.go diff --git a/command/agent/config.go b/command/agent/config.go index 1b981c54e4..425895f49f 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -11,12 +11,18 @@ import ( "path/filepath" "sort" "strings" + "time" ) // Config is the configuration that can be set for an Agent. // Some of this is configurable as CLI flags, but most must // be set using a configuration file. type Config struct { + // AEInterval controls the anti-entropy interval. This is how often + // the agent attempts to reconcile it's local state with the server' + // representation of our state. Defaults to every 60s. + AEInterval time.Duration + // Bootstrap is used to bring up the first Consul server, and // permits that node to elect itself leader Bootstrap bool @@ -96,6 +102,7 @@ type dirEnts []os.FileInfo // DefaultConfig is used to return a sane default configuration func DefaultConfig() *Config { return &Config{ + AEInterval: time.Minute, Datacenter: consul.DefaultDC, DNSAddr: "127.0.0.1:8600", Domain: "consul.", diff --git a/command/agent/util.go b/command/agent/util.go new file mode 100644 index 0000000000..9d2531a938 --- /dev/null +++ b/command/agent/util.go @@ -0,0 +1,25 @@ +package agent + +import ( + "math" + "time" +) + +const ( + // This scale factor means we will add a minute after we + // cross 128 nodes, another at 256, another at 512, etc. + // By 8192 nodes, we will scale up by a factor of 8 + aeScaleThreshold = 128 +) + +// aeScale is used to scale the time interval at which anti-entropy +// take place. It is used to prevent saturation as the cluster size grows +func aeScale(interval time.Duration, n int) time.Duration { + // Don't scale until we cross the threshold + if n <= aeScaleThreshold { + return interval + } + + multiplier := math.Ceil(math.Log2(float64(n))-math.Log2(aeScaleThreshold)) + 1.0 + return time.Duration(multiplier) * interval +} diff --git a/command/agent/util_test.go b/command/agent/util_test.go new file mode 100644 index 0000000000..d33894d31f --- /dev/null +++ b/command/agent/util_test.go @@ -0,0 +1,22 @@ +package agent + +import ( + "testing" + "time" +) + +func TestAEScale(t *testing.T) { + intv := time.Minute + if v := aeScale(intv, 100); v != intv { + t.Fatalf("Bad: %v", v) + } + if v := aeScale(intv, 200); v != 2*intv { + t.Fatalf("Bad: %v", v) + } + if v := aeScale(intv, 1000); v != 4*intv { + t.Fatalf("Bad: %v", v) + } + if v := aeScale(intv, 10000); v != 8*intv { + t.Fatalf("Bad: %v", v) + } +}