diff --git a/api/envoy/api/v2/core/config_source.proto b/api/envoy/api/v2/core/config_source.proto index 8b6014dcbf9d3..913f3876115ce 100644 --- a/api/envoy/api/v2/core/config_source.proto +++ b/api/envoy/api/v2/core/config_source.proto @@ -112,13 +112,12 @@ message ConfigSource { AggregatedConfigSource ads = 3; } - // Optional initialization timeout. // When this timeout is specified, Envoy will wait no longer than the specified time for first // config response on this xDS subscription during the :ref:`initialization process // `. After reaching the timeout, Envoy will move to the next // initialization phase, even if the first config is not delivered yet. The timer is activated // when the xDS API subscription starts, and is disarmed on first config update or on error. 0 // means no timeout - Envoy will wait indefinitely for the first xDS config (unless another - // timeout applies). Default 0. + // timeout applies). The default is 15s. google.protobuf.Duration initial_fetch_timeout = 4; } diff --git a/docs/root/intro/arch_overview/operations/init.rst b/docs/root/intro/arch_overview/operations/init.rst index 2e05c5a750564..4ce245d78f51b 100644 --- a/docs/root/intro/arch_overview/operations/init.rst +++ b/docs/root/intro/arch_overview/operations/init.rst @@ -10,20 +10,24 @@ accepting new connections. * During startup, the :ref:`cluster manager ` goes through a multi-phase initialization where it first initializes static/DNS clusters, then predefined :ref:`EDS ` clusters. Then it initializes - :ref:`CDS ` if applicable, waits for one response (or failure), + :ref:`CDS ` if applicable, waits for one response (or failure) + for a :ref:`bounded period of time `, and does the same primary/secondary initialization of CDS provided clusters. * If clusters use :ref:`active health checking `, Envoy also does a single active health check round. * Once cluster manager initialization is done, :ref:`RDS ` and - :ref:`LDS ` initialize (if applicable). The server - doesn't start accepting connections until there has been at least one response (or failure) for - LDS/RDS requests. -* If LDS itself returns a listener that needs an RDS response, Envoy further waits until an RDS + :ref:`LDS ` initialize (if applicable). The server waits + for a :ref:`bounded period of time ` + for at least one response (or failure) for LDS/RDS requests. After which, it starts accepting connections. +* If LDS itself returns a listener that needs an RDS response, Envoy further waits for + a :ref:`bounded period of time ` until an RDS response (or failure) is received. Note that this process takes place on every future listener addition via LDS and is known as :ref:`listener warming `. * After all of the previous steps have taken place, the listeners start accepting new connections. This flow ensures that during hot restart the new process is fully capable of accepting and processing new connections before the draining of the old process begins. -All mentioned "waiting for one response" periods can be limited by setting corresponding -:ref:`initial_fetch_timeout `. +A key design principle of initialization is that an Envoy is always guaranteed to initialize within +:ref:`initial_fetch_timeout `, +with a best effort made to obtain the complete set of xDS configuration within that subject to the +management server availability. diff --git a/docs/root/intro/version_history.rst b/docs/root/intro/version_history.rst index ab727239f4447..e38946186a4e3 100644 --- a/docs/root/intro/version_history.rst +++ b/docs/root/intro/version_history.rst @@ -5,6 +5,7 @@ Version history ================ * admin: added ability to configure listener :ref:`socket options `. * config: async data access for local and remote data source. +* config: changed the default value of :ref:`initial_fetch_timeout ` from 0s to 15s. This is a change in behaviour in the sense that Envoy will move to the next initialization phase, even if the first config is not delivered in 15s. Refer to :ref:`initialization process ` for more details. * listeners: added :ref:`HTTP inspector listener filter `. * http: added the ability to reject HTTP/1.1 requests with invalid HTTP header values, using the runtime feature `envoy.reloadable_features.strict_header_validation`. diff --git a/source/common/config/utility.cc b/source/common/config/utility.cc index d22cc0a4cca6f..84dedbcda38f3 100644 --- a/source/common/config/utility.cc +++ b/source/common/config/utility.cc @@ -180,7 +180,7 @@ std::chrono::milliseconds Utility::apiConfigSourceRequestTimeout( std::chrono::milliseconds Utility::configSourceInitialFetchTimeout(const envoy::api::v2::core::ConfigSource& config_source) { return std::chrono::milliseconds( - PROTOBUF_GET_MS_OR_DEFAULT(config_source, initial_fetch_timeout, 0)); + PROTOBUF_GET_MS_OR_DEFAULT(config_source, initial_fetch_timeout, 15000)); } void Utility::translateRdsConfig( diff --git a/test/common/config/subscription_factory_impl_test.cc b/test/common/config/subscription_factory_impl_test.cc index 9c10b7dad2822..c72b02d146083 100644 --- a/test/common/config/subscription_factory_impl_test.cc +++ b/test/common/config/subscription_factory_impl_test.cc @@ -226,7 +226,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscriptionCustomRequestTimeout) { EXPECT_CALL(cm_, clusters()).WillOnce(Return(cluster_map)); EXPECT_CALL(cluster, info()).Times(2); EXPECT_CALL(*cluster.info_, addedViaApi()); - EXPECT_CALL(dispatcher_, createTimer_(_)); + EXPECT_CALL(dispatcher_, createTimer_(_)).Times(2); EXPECT_CALL(cm_, httpAsyncClientForCluster("static_cluster")); EXPECT_CALL( cm_.async_client_, @@ -246,7 +246,7 @@ TEST_F(SubscriptionFactoryTest, HttpSubscription) { EXPECT_CALL(cm_, clusters()).WillOnce(Return(cluster_map)); EXPECT_CALL(cluster, info()).Times(2); EXPECT_CALL(*cluster.info_, addedViaApi()); - EXPECT_CALL(dispatcher_, createTimer_(_)); + EXPECT_CALL(dispatcher_, createTimer_(_)).Times(2); EXPECT_CALL(cm_, httpAsyncClientForCluster("static_cluster")); EXPECT_CALL(cm_.async_client_, send_(_, _, _)) .WillOnce(Invoke([this](Http::MessagePtr& request, Http::AsyncClient::Callbacks&, @@ -301,7 +301,7 @@ TEST_F(SubscriptionFactoryTest, GrpcSubscription) { return async_client_factory; })); EXPECT_CALL(random_, random()); - EXPECT_CALL(dispatcher_, createTimer_(_)); + EXPECT_CALL(dispatcher_, createTimer_(_)).Times(2); EXPECT_CALL(callbacks_, onConfigUpdateFailed(_)); subscriptionFromConfigSource(config)->start({"static_cluster"}); } diff --git a/test/common/config/utility_test.cc b/test/common/config/utility_test.cc index 30d8fa8b3f3b4..90573d4f7d9b8 100644 --- a/test/common/config/utility_test.cc +++ b/test/common/config/utility_test.cc @@ -55,7 +55,7 @@ TEST(UtilityTest, ApiConfigSourceRequestTimeout) { TEST(UtilityTest, ConfigSourceDefaultInitFetchTimeout) { envoy::api::v2::core::ConfigSource config_source; - EXPECT_EQ(0, Utility::configSourceInitialFetchTimeout(config_source).count()); + EXPECT_EQ(15000, Utility::configSourceInitialFetchTimeout(config_source).count()); } TEST(UtilityTest, ConfigSourceInitFetchTimeout) {