diff --git a/src/cmd/services/m3dbnode/config/config_test.go b/src/cmd/services/m3dbnode/config/config_test.go index 1ac0e0b5d1..3f3ce59354 100644 --- a/src/cmd/services/m3dbnode/config/config_test.go +++ b/src/cmd/services/m3dbnode/config/config_test.go @@ -332,8 +332,6 @@ db: service: null static: null seedNodes: null - namespaceResolutionTimeout: 0s - topologyResolutionTimeout: 0s writeConsistencyLevel: 2 readConsistencyLevel: 2 connectConsistencyLevel: 0 @@ -577,8 +575,6 @@ db: trustedCaFile: "" clientCertAuth: false autoTls: false - namespaceResolutionTimeout: 0s - topologyResolutionTimeout: 0s hashing: seed: 42 writeNewSeriesAsync: true diff --git a/src/dbnode/environment/config.go b/src/dbnode/environment/config.go index b66371f10b..35bea74a7e 100644 --- a/src/dbnode/environment/config.go +++ b/src/dbnode/environment/config.go @@ -23,7 +23,6 @@ package environment import ( "errors" "fmt" - "time" "github.com/m3db/m3/src/dbnode/kvconfig" "github.com/m3db/m3/src/dbnode/sharding" @@ -38,10 +37,6 @@ import ( "github.com/m3db/m3x/instrument" ) -const ( - defaultSDTimeout = time.Duration(0) // Wait indefinitely by default -) - var ( errInvalidConfig = errors.New("must supply either service or static config") ) @@ -56,12 +51,6 @@ type Configuration struct { // Presence of a (etcd) server in this config denotes an embedded cluster SeedNodes *SeedNodesConfig `yaml:"seedNodes"` - - // NamespaceResolutionTimeout is the maximum time to wait to discover namespaces from KV - NamespaceResolutionTimeout time.Duration `yaml:"namespaceResolutionTimeout"` - - // TopologyResolutionTimeout is the maximum time to wait for a topology from KV - TopologyResolutionTimeout time.Duration `yaml:"topologyResolutionTimeout"` } // SeedNodesConfig defines fields for seed node @@ -109,11 +98,9 @@ type ConfigureResults struct { // ConfigurationParameters are options used to create new ConfigureResults type ConfigurationParameters struct { - InstrumentOpts instrument.Options - HashingSeed uint32 - HostID string - NamespaceResolutionTimeout time.Duration - TopologyResolutionTimeout time.Duration + InstrumentOpts instrument.Options + HashingSeed uint32 + HostID string } // Configure creates a new ConfigureResults @@ -136,14 +123,11 @@ func (c Configuration) Configure(cfgParams ConfigurationParameters) (ConfigureRe } func (c Configuration) configureDynamic(cfgParams ConfigurationParameters) (ConfigureResults, error) { - sdTimeout := defaultSDTimeout - if initTimeout := c.Service.SDConfig.InitTimeout; initTimeout != nil && *initTimeout != 0 { - sdTimeout = *initTimeout - } - configSvcClientOpts := c.Service.NewOptions(). SetInstrumentOptions(cfgParams.InstrumentOpts). - SetServicesOptions(c.Service.SDConfig.NewOptions().SetInitTimeout(sdTimeout)) + // Set timeout to zero so it will wait indefinitely for the + // initial value. + SetServicesOptions(services.NewOptions().SetInitTimeout(0)) configSvcClient, err := etcdclient.NewConfigServiceClient(configSvcClientOpts) if err != nil { err = fmt.Errorf("could not create m3cluster client: %v", err) @@ -153,8 +137,7 @@ func (c Configuration) configureDynamic(cfgParams ConfigurationParameters) (Conf dynamicOpts := namespace.NewDynamicOptions(). SetInstrumentOptions(cfgParams.InstrumentOpts). SetConfigServiceClient(configSvcClient). - SetNamespaceRegistryKey(kvconfig.NamespacesKey). - SetInitTimeout(cfgParams.NamespaceResolutionTimeout) + SetNamespaceRegistryKey(kvconfig.NamespacesKey) nsInit := namespace.NewDynamicInitializer(dynamicOpts) serviceID := services.NewServiceID(). @@ -167,8 +150,7 @@ func (c Configuration) configureDynamic(cfgParams ConfigurationParameters) (Conf SetServiceID(serviceID). SetQueryOptions(services.NewQueryOptions().SetIncludeUnhealthy(true)). SetInstrumentOptions(cfgParams.InstrumentOpts). - SetHashGen(sharding.NewHashGenWithSeed(cfgParams.HashingSeed)). - SetInitTimeout(cfgParams.TopologyResolutionTimeout) + SetHashGen(sharding.NewHashGenWithSeed(cfgParams.HashingSeed)) topoInit := topology.NewDynamicInitializer(topoOpts) kv, err := configSvcClient.KV() diff --git a/src/dbnode/server/server.go b/src/dbnode/server/server.go index 68a4f383d5..1db1004641 100644 --- a/src/dbnode/server/server.go +++ b/src/dbnode/server/server.go @@ -80,10 +80,8 @@ import ( ) const ( - bootstrapConfigInitTimeout = 10 * time.Second - serverGracefulCloseTimeout = 10 * time.Second - defaultNamespaceResolutionTimeout = time.Minute - defaultTopologyResolutionTimeout = time.Minute + bootstrapConfigInitTimeout = 10 * time.Second + serverGracefulCloseTimeout = 10 * time.Second ) // RunOptions provides options for running the server @@ -378,21 +376,9 @@ func Run(runOpts RunOptions) { if cfg.EnvironmentConfig.Static == nil { logger.Info("creating dynamic config service client with m3cluster") - namespaceResolutionTimeout := cfg.EnvironmentConfig.NamespaceResolutionTimeout - if namespaceResolutionTimeout <= 0 { - namespaceResolutionTimeout = defaultNamespaceResolutionTimeout - } - - topologyResolutionTimeout := cfg.EnvironmentConfig.TopologyResolutionTimeout - if topologyResolutionTimeout <= 0 { - topologyResolutionTimeout = defaultTopologyResolutionTimeout - } - envCfg, err = cfg.EnvironmentConfig.Configure(environment.ConfigurationParameters{ - InstrumentOpts: iopts, - HashingSeed: cfg.Hashing.Seed, - NamespaceResolutionTimeout: namespaceResolutionTimeout, - TopologyResolutionTimeout: topologyResolutionTimeout, + InstrumentOpts: iopts, + HashingSeed: cfg.Hashing.Seed, }) if err != nil { logger.Fatalf("could not initialize dynamic config: %v", err) diff --git a/src/dbnode/storage/namespace/dynamic.go b/src/dbnode/storage/namespace/dynamic.go index 10496b48aa..9d0262f7c6 100644 --- a/src/dbnode/storage/namespace/dynamic.go +++ b/src/dbnode/storage/namespace/dynamic.go @@ -34,7 +34,6 @@ import ( ) var ( - errInitTimeOut = errors.New("timed out waiting for initial value") errRegistryAlreadyClosed = errors.New("registry already closed") errInvalidRegistry = errors.New("could not parse latest value from config service") ) @@ -108,11 +107,10 @@ func newDynamicRegistry(opts DynamicOptions) (Registry, error) { } logger := opts.InstrumentOptions().Logger() - if err = waitOnInit(watch, opts.InitTimeout()); err != nil { - logger.Errorf("dynamic namespace registry initialization timed out in %s: %v", - opts.InitTimeout().String(), err) - return nil, err - } + logger.Info(`waiting for dynamic namespace registry initialization. + If this takes a long time, make sure that a namespace is configured`) + <-watch.C() + logger.Info("initial namespace value received") initValue := watch.Get() m, err := getMapFromUpdate(initValue) @@ -238,18 +236,6 @@ func (r *dynamicRegistry) Close() error { return nil } -func waitOnInit(w kv.ValueWatch, d time.Duration) error { - if d <= 0 { - return nil - } - select { - case <-w.C(): - return nil - case <-time.After(d): - return errInitTimeOut - } -} - func getMapFromUpdate(val kv.Value) (Map, error) { if val == nil { return nil, errInvalidRegistry diff --git a/src/dbnode/storage/namespace/dynamic_options.go b/src/dbnode/storage/namespace/dynamic_options.go index a0d8323da9..60597d701e 100644 --- a/src/dbnode/storage/namespace/dynamic_options.go +++ b/src/dbnode/storage/namespace/dynamic_options.go @@ -97,13 +97,3 @@ func (o *dynamicOpts) SetNamespaceRegistryKey(k string) DynamicOptions { func (o *dynamicOpts) NamespaceRegistryKey() string { return o.nsRegistryKey } - -func (o *dynamicOpts) SetInitTimeout(value time.Duration) DynamicOptions { - opts := *o - opts.initTimeout = value - return &opts -} - -func (o *dynamicOpts) InitTimeout() time.Duration { - return o.initTimeout -} diff --git a/src/dbnode/storage/namespace/dynamic_test.go b/src/dbnode/storage/namespace/dynamic_test.go index 83fc4e4df1..6930066361 100644 --- a/src/dbnode/storage/namespace/dynamic_test.go +++ b/src/dbnode/storage/namespace/dynamic_test.go @@ -54,7 +54,6 @@ func newTestOpts(t *testing.T, ctrl *gomock.Controller, watchable kv.ValueWatcha instrument.NewOptions(). SetReportInterval(10 * time.Millisecond). SetMetricsScope(ts)). - SetInitTimeout(100 * time.Millisecond). SetConfigServiceClient(mockCSClient) return opts @@ -78,20 +77,6 @@ func currentVersionMetrics(opts DynamicOptions) float64 { return g.Value() } -func TestInitializerTimeout(t *testing.T) { - defer leaktest.CheckTimeout(t, time.Second)() - - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - w := newTestWatchable(t, nil) - opts := newTestOpts(t, ctrl, w) - init := NewDynamicInitializer(opts) - _, err := init.Init() - require.Error(t, err) - require.Equal(t, errInitTimeOut, err) -} - func TestInitializerNoTimeout(t *testing.T) { defer leaktest.CheckTimeout(t, time.Second)() diff --git a/src/dbnode/storage/namespace/namespace_mock.go b/src/dbnode/storage/namespace/namespace_mock.go index b487a4f704..fb8febd906 100644 --- a/src/dbnode/storage/namespace/namespace_mock.go +++ b/src/dbnode/storage/namespace/namespace_mock.go @@ -738,27 +738,3 @@ func (m *MockDynamicOptions) NamespaceRegistryKey() string { func (mr *MockDynamicOptionsMockRecorder) NamespaceRegistryKey() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NamespaceRegistryKey", reflect.TypeOf((*MockDynamicOptions)(nil).NamespaceRegistryKey)) } - -// SetInitTimeout mocks base method -func (m *MockDynamicOptions) SetInitTimeout(value time.Duration) DynamicOptions { - ret := m.ctrl.Call(m, "SetInitTimeout", value) - ret0, _ := ret[0].(DynamicOptions) - return ret0 -} - -// SetInitTimeout indicates an expected call of SetInitTimeout -func (mr *MockDynamicOptionsMockRecorder) SetInitTimeout(value interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetInitTimeout", reflect.TypeOf((*MockDynamicOptions)(nil).SetInitTimeout), value) -} - -// InitTimeout mocks base method -func (m *MockDynamicOptions) InitTimeout() time.Duration { - ret := m.ctrl.Call(m, "InitTimeout") - ret0, _ := ret[0].(time.Duration) - return ret0 -} - -// InitTimeout indicates an expected call of InitTimeout -func (mr *MockDynamicOptionsMockRecorder) InitTimeout() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitTimeout", reflect.TypeOf((*MockDynamicOptions)(nil).InitTimeout)) -} diff --git a/src/dbnode/storage/namespace/types.go b/src/dbnode/storage/namespace/types.go index 16e82111e2..64f1764dac 100644 --- a/src/dbnode/storage/namespace/types.go +++ b/src/dbnode/storage/namespace/types.go @@ -182,10 +182,4 @@ type DynamicOptions interface { // NamespaceRegistryKey returns the kv-store key used for the // NamespaceRegistry NamespaceRegistryKey() string - - // SetInitTimeout sets the waiting time for dynamic topology to be initialized - SetInitTimeout(value time.Duration) DynamicOptions - - // InitTimeout returns the waiting time for dynamic topology to be initialized - InitTimeout() time.Duration } diff --git a/src/dbnode/topology/dynamic.go b/src/dbnode/topology/dynamic.go index 722994f5bc..8c5cec651b 100644 --- a/src/dbnode/topology/dynamic.go +++ b/src/dbnode/topology/dynamic.go @@ -23,7 +23,6 @@ package topology import ( "errors" "sync" - "time" "github.com/m3db/m3/src/dbnode/sharding" "github.com/m3db/m3cluster/placement" @@ -34,7 +33,6 @@ import ( ) var ( - errInitTimeOut = errors.New("timed out waiting for initial value") errInvalidService = errors.New("service topology is invalid") errUnexpectedShard = errors.New("shard is unexpected") errMissingShard = errors.New("shard is missing") @@ -90,17 +88,16 @@ func newDynamicTopology(opts DynamicOptions) (DynamicTopology, error) { if err != nil { return nil, err } - watch, err := services.Watch(opts.ServiceID(), opts.QueryOptions()) - if err != nil { - return nil, err - } logger := opts.InstrumentOptions().Logger() - if err = waitOnInit(watch, opts.InitTimeout()); err != nil { - logger.Errorf("dynamic topology initialization timed out in %s: %v", - opts.InitTimeout().String(), err) + logger.Info(`waiting for dynamic topology initialization. + If this takes a long time, make sure that a topology / placement is configured`) + watch, err := services.Watch(opts.ServiceID(), opts.QueryOptions()) + if err != nil { return nil, err } + <-watch.C() + logger.Info("initial topology / placement value received") m, err := getMapFromUpdate(watch.Get(), opts.HashGen()) if err != nil { @@ -185,19 +182,6 @@ func (t *dynamicTopology) MarkShardsAvailable( return ps.MarkShardsAvailable(instanceID, shardIDs...) } -func waitOnInit(w services.Watch, d time.Duration) error { - if d <= 0 { - <-w.C() // Wait for the first placement indefinitely - return nil - } - select { - case <-w.C(): - return nil - case <-time.After(d): - return errInitTimeOut - } -} - func getMapFromUpdate(data interface{}, hashGen sharding.HashGen) (Map, error) { service, ok := data.(services.Service) if !ok { diff --git a/src/dbnode/topology/dynamic_test.go b/src/dbnode/topology/dynamic_test.go index f9521d4f44..6a6d019c05 100644 --- a/src/dbnode/topology/dynamic_test.go +++ b/src/dbnode/topology/dynamic_test.go @@ -54,16 +54,6 @@ func testFinish(ctrl *gomock.Controller, watch *testWatch) { ctrl.Finish() } -func TestInitTimeout(t *testing.T) { - ctrl := gomock.NewController(t) - opts, w := testSetup(ctrl) - defer testFinish(ctrl, w) - - topo, err := newDynamicTopology(opts.SetInitTimeout(10 * time.Millisecond)) - assert.Equal(t, errInitTimeOut, err) - assert.Nil(t, topo) -} - func TestInitNoTimeout(t *testing.T) { ctrl := gomock.NewController(t) opts, w := testSetup(ctrl) diff --git a/src/dbnode/topology/options.go b/src/dbnode/topology/options.go index 181850f717..af88fbcb0b 100644 --- a/src/dbnode/topology/options.go +++ b/src/dbnode/topology/options.go @@ -194,15 +194,6 @@ func (o *dynamicOptions) InstrumentOptions() instrument.Options { return o.instrumentOptions } -func (o *dynamicOptions) SetInitTimeout(value time.Duration) DynamicOptions { - o.initTimeout = value - return o -} - -func (o *dynamicOptions) InitTimeout() time.Duration { - return o.initTimeout -} - func (o *dynamicOptions) SetHashGen(h sharding.HashGen) DynamicOptions { o.hashGen = h return o diff --git a/src/dbnode/topology/topology_mock.go b/src/dbnode/topology/topology_mock.go index 835408bb88..eadd373b43 100644 --- a/src/dbnode/topology/topology_mock.go +++ b/src/dbnode/topology/topology_mock.go @@ -26,7 +26,6 @@ package topology import ( "reflect" - "time" "github.com/m3db/m3/src/dbnode/sharding" "github.com/m3db/m3cluster/client" @@ -790,30 +789,6 @@ func (mr *MockDynamicOptionsMockRecorder) InstrumentOptions() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstrumentOptions", reflect.TypeOf((*MockDynamicOptions)(nil).InstrumentOptions)) } -// SetInitTimeout mocks base method -func (m *MockDynamicOptions) SetInitTimeout(value time.Duration) DynamicOptions { - ret := m.ctrl.Call(m, "SetInitTimeout", value) - ret0, _ := ret[0].(DynamicOptions) - return ret0 -} - -// SetInitTimeout indicates an expected call of SetInitTimeout -func (mr *MockDynamicOptionsMockRecorder) SetInitTimeout(value interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetInitTimeout", reflect.TypeOf((*MockDynamicOptions)(nil).SetInitTimeout), value) -} - -// InitTimeout mocks base method -func (m *MockDynamicOptions) InitTimeout() time.Duration { - ret := m.ctrl.Call(m, "InitTimeout") - ret0, _ := ret[0].(time.Duration) - return ret0 -} - -// InitTimeout indicates an expected call of InitTimeout -func (mr *MockDynamicOptionsMockRecorder) InitTimeout() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitTimeout", reflect.TypeOf((*MockDynamicOptions)(nil).InitTimeout)) -} - // SetHashGen mocks base method func (m *MockDynamicOptions) SetHashGen(h sharding.HashGen) DynamicOptions { ret := m.ctrl.Call(m, "SetHashGen", h) diff --git a/src/dbnode/topology/types.go b/src/dbnode/topology/types.go index 485ed15dda..cbb7d2e7f5 100644 --- a/src/dbnode/topology/types.go +++ b/src/dbnode/topology/types.go @@ -21,8 +21,6 @@ package topology import ( - "time" - "github.com/m3db/m3/src/dbnode/sharding" "github.com/m3db/m3cluster/client" "github.com/m3db/m3cluster/services" @@ -205,12 +203,6 @@ type DynamicOptions interface { // InstrumentOptions returns the instrumentation options InstrumentOptions() instrument.Options - // SetInitTimeout sets the waiting time for dynamic topology to be initialized - SetInitTimeout(value time.Duration) DynamicOptions - - // InitTimeout returns the waiting time for dynamic topology to be initialized - InitTimeout() time.Duration - // SetHashGen sets the HashGen function SetHashGen(h sharding.HashGen) DynamicOptions