You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by is...@apache.org on 2021/01/29 13:29:15 UTC
[ignite] branch master updated: IGNITE-13763: Add connection limit
This is an automated email from the ASF dual-hosted git repository.
isapego pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 165d5cc IGNITE-13763: Add connection limit
165d5cc is described below
commit 165d5ccad1a780b008dfe8cb953bc6a0f6347067
Author: Igor Sapego <is...@apache.org>
AuthorDate: Fri Jan 29 16:28:07 2021 +0300
IGNITE-13763: Add connection limit
This closes #8726
---
.../cpp/thin-client-test/config/log/log4j-0.xml | 42 +++++++++++++
.../cpp/thin-client-test/config/with-logging-0.xml | 36 +++++++++++
.../thin-client-test/config/with-logging-base.xml | 70 ++++++++++++++++++++++
.../cpp/thin-client-test/include/test_utils.h | 8 +++
.../thin-client-test/src/ignite_client_test.cpp | 68 +++++++++++++++++++--
.../cpp/thin-client-test/src/test_utils.cpp | 17 ++++++
.../ignite/thin/ignite_client_configuration.h | 37 +++++++++++-
.../cpp/thin-client/src/impl/data_router.cpp | 10 ++++
8 files changed, 283 insertions(+), 5 deletions(-)
diff --git a/modules/platforms/cpp/thin-client-test/config/log/log4j-0.xml b/modules/platforms/cpp/thin-client-test/config/log/log4j-0.xml
new file mode 100644
index 0000000..90a1cb8
--- /dev/null
+++ b/modules/platforms/cpp/thin-client-test/config/log/log4j-0.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<Configuration>
+ <Appenders>
+ <Console name="CONSOLE" target="SYSTEM_OUT">
+ <PatternLayout pattern="[%d{ISO8601}][%-5p][%t][%c{1}] %m%n"/>
+ </Console>
+ <RollingFile name="FILE" append="true"
+ filePattern="logs/ignite-log-0-%i.log.gz"
+ fileName="logs/ignite-log-0.txt">
+ <PatternLayout pattern="%m%n"/>
+ <Policies>
+ <SizeBasedTriggeringPolicy size="10MB" />
+ </Policies>
+ <DefaultRolloverStrategy max="10"/>
+ </RollingFile>
+ </Appenders>
+ <Loggers>
+ <Logger name="org.apache.ignite.internal.processors.odbc.ClientListenerNioListener" level="debug"/>
+ <Root level="info">
+ <AppenderRef ref="CONSOLE"/>
+ <AppenderRef ref="FILE"/>
+ </Root>
+ </Loggers>
+</Configuration>
diff --git a/modules/platforms/cpp/thin-client-test/config/with-logging-0.xml b/modules/platforms/cpp/thin-client-test/config/with-logging-0.xml
new file mode 100644
index 0000000..3a52964
--- /dev/null
+++ b/modules/platforms/cpp/thin-client-test/config/with-logging-0.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <import resource="with-logging-base.xml"/>
+
+ <bean parent="test.cfg">
+ <property name="gridLogger">
+ <bean class="org.apache.ignite.logger.log4j2.Log4J2Logger">
+ <constructor-arg type="java.lang.String" value="${IGNITE_NATIVE_TEST_CPP_THIN_CONFIG_PATH}/log/log4j-0.xml"/>
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/thin-client-test/config/with-logging-base.xml b/modules/platforms/cpp/thin-client-test/config/with-logging-base.xml
new file mode 100644
index 0000000..cba28da
--- /dev/null
+++ b/modules/platforms/cpp/thin-client-test/config/with-logging-base.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util
+ http://www.springframework.org/schema/util/spring-util.xsd">
+
+ <!--
+ Initialize property configurer so we can reference environment variables.
+ -->
+ <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+ <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_FALLBACK"/>
+ <property name="searchSystemEnvironment" value="true"/>
+ </bean>
+
+ <bean abstract="true" id="test.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
+ <property name="localHost" value="127.0.0.1"/>
+ <property name="connectorConfiguration"><null/></property>
+
+ <property name="clientConnectorConfiguration">
+ <bean class="org.apache.ignite.configuration.ClientConnectorConfiguration">
+ <property name="host" value="127.0.0.1"/>
+ <property name="port" value="11110"/>
+ </bean>
+ </property>
+
+ <!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
+ <property name="discoverySpi">
+ <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
+ <property name="ipFinder">
+ <!--
+ Ignite provides several options for automatic discovery that can be used
+ instead os static IP based discovery.
+ -->
+ <!-- Uncomment static IP finder to enable static-based discovery of initial nodes. -->
+ <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
+ <property name="addresses">
+ <list>
+ <!-- In distributed environment, replace with actual host IP address. -->
+ <value>127.0.0.1:47500</value>
+ </list>
+ </property>
+ </bean>
+ </property>
+ <property name="socketTimeout" value="300" />
+ </bean>
+ </property>
+ </bean>
+</beans>
diff --git a/modules/platforms/cpp/thin-client-test/include/test_utils.h b/modules/platforms/cpp/thin-client-test/include/test_utils.h
index 0d8e2b6..e0f0ff5 100644
--- a/modules/platforms/cpp/thin-client-test/include/test_utils.h
+++ b/modules/platforms/cpp/thin-client-test/include/test_utils.h
@@ -75,6 +75,14 @@ namespace ignite_test
* Remove all the LFS artifacts.
*/
void ClearLfs();
+
+ /**
+ * Get a number of occurrences of a given string in the specified file.
+ * @param filePath File path.
+ * @param line Line to find.
+ * @return Number of occurrences.
+ */
+ size_t GetLineOccurrencesInFile(const std::string& filePath, const std::string& line);
}
#endif // _IGNITE_THIN_CLIENT_TEST_TEST_UTILS
\ No newline at end of file
diff --git a/modules/platforms/cpp/thin-client-test/src/ignite_client_test.cpp b/modules/platforms/cpp/thin-client-test/src/ignite_client_test.cpp
index 0010d4f..bb50b16 100644
--- a/modules/platforms/cpp/thin-client-test/src/ignite_client_test.cpp
+++ b/modules/platforms/cpp/thin-client-test/src/ignite_client_test.cpp
@@ -32,7 +32,7 @@ class IgniteClientTestSuiteFixture
public:
IgniteClientTestSuiteFixture()
{
- serverNode = ignite_test::StartCrossPlatformServerNode("cache.xml", "ServerNode");
+ // No-op.
}
~IgniteClientTestSuiteFixture()
@@ -40,15 +40,53 @@ public:
ignite::Ignition::StopAll(false);
}
-private:
- /** Server node. */
- ignite::Ignite serverNode;
+ /**
+ * Check that if client started with given configuration and connection limit then the actual number of active
+ * connections is equal to the expected value.
+ *
+ * @param cfg Client configuration.
+ * @param limit Limit to set
+ * @param expect Expected connections number.
+ */
+ void CheckConnectionsNum(IgniteClientConfiguration &cfg, uint32_t limit, size_t expect)
+ {
+ cfg.SetConnectionsLimit(limit);
+ IgniteClient client = IgniteClient::Start(cfg);
+
+ BOOST_CHECK_EQUAL(GetActiveConnections(), expect);
+ }
+
+ /**
+ * Get Number of active connections.
+ *
+ * @return Number of active connections.
+ */
+ static size_t GetActiveConnections()
+ {
+ size_t connected = ignite_test::GetLineOccurrencesInFile("logs/ignite-log-0.txt", "Client connected");
+ size_t disconnected = ignite_test::GetLineOccurrencesInFile("logs/ignite-log-0.txt", "Client disconnected");
+
+ return connected - disconnected;
+ }
+
+ /**
+ * Start node with logging.
+ *
+ * @param id Node id. Used to identify node and log.
+ */
+ ignite::Ignite StartNodeWithLog(const std::string& id)
+ {
+ std::string nodeName = "ServerNode" + id;
+ return ignite_test::StartCrossPlatformServerNode("with-logging-0.xml", nodeName.c_str());
+ }
};
BOOST_FIXTURE_TEST_SUITE(IgniteClientTestSuite, IgniteClientTestSuiteFixture)
BOOST_AUTO_TEST_CASE(IgniteClientConnection)
{
+ ignite::Ignite serverNode = ignite_test::StartCrossPlatformServerNode("cache.xml", "ServerNode");
+
IgniteClientConfiguration cfg;
cfg.SetEndPoints("127.0.0.1:11110");
@@ -58,6 +96,8 @@ BOOST_AUTO_TEST_CASE(IgniteClientConnection)
BOOST_AUTO_TEST_CASE(IgniteClientConnectionFailover)
{
+ ignite::Ignite serverNode = ignite_test::StartCrossPlatformServerNode("cache.xml", "ServerNode");
+
IgniteClientConfiguration cfg;
cfg.SetEndPoints("127.0.0.1:11109..11111");
@@ -65,4 +105,24 @@ BOOST_AUTO_TEST_CASE(IgniteClientConnectionFailover)
IgniteClient::Start(cfg);
}
+BOOST_AUTO_TEST_CASE(IgniteClientConnectionLimit)
+{
+ ignite::common::DeletePath("logs");
+
+ ignite::Ignite serverNode0 = StartNodeWithLog("0");
+ ignite::Ignite serverNode1 = StartNodeWithLog("1");
+ ignite::Ignite serverNode2 = StartNodeWithLog("2");
+
+ IgniteClientConfiguration cfg;
+
+ cfg.SetEndPoints("127.0.0.1:11110,127.0.0.1:11111,127.0.0.1:11112");
+
+ CheckConnectionsNum(cfg, 0, 3);
+ CheckConnectionsNum(cfg, 1, 1);
+ CheckConnectionsNum(cfg, 2, 2);
+ CheckConnectionsNum(cfg, 3, 3);
+ CheckConnectionsNum(cfg, 4, 3);
+ CheckConnectionsNum(cfg, 100500, 3);
+}
+
BOOST_AUTO_TEST_SUITE_END()
diff --git a/modules/platforms/cpp/thin-client-test/src/test_utils.cpp b/modules/platforms/cpp/thin-client-test/src/test_utils.cpp
index 427490b..fd179d2 100644
--- a/modules/platforms/cpp/thin-client-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/thin-client-test/src/test_utils.cpp
@@ -19,6 +19,8 @@
#include <cassert>
+#include <fstream>
+
#include <ignite/common/platform_utils.h>
#include "test_utils.h"
@@ -136,4 +138,19 @@ namespace ignite_test
ignite::common::DeletePath(workDir);
}
+
+ size_t GetLineOccurrencesInFile(const std::string& filePath, const std::string& line)
+ {
+ std::ifstream file(filePath.c_str());
+
+ size_t cnt = 0;
+ std::string current;
+ while (std::getline(file, current))
+ {
+ if (current.find(line) != std::string::npos)
+ ++cnt;
+ }
+
+ return cnt;
+ }
}
diff --git a/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h
index d14f830..617009f 100644
--- a/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h
+++ b/modules/platforms/cpp/thin-client/include/ignite/thin/ignite_client_configuration.h
@@ -46,7 +46,8 @@ namespace ignite
*/
IgniteClientConfiguration() :
sslMode(SslMode::DISABLE),
- partitionAwareness(false)
+ partitionAwareness(false),
+ connectionsLimit(0)
{
// No-op.
}
@@ -230,6 +231,37 @@ namespace ignite
return partitionAwareness;
}
+ /**
+ * Get connection limit.
+ *
+ * By default, C++ thin client establishes a connection to every server node listed in @c endPoints. Use
+ * this setting to limit the number of active connections. This reduces initial connection time and the
+ * resource usage, but can have a negative effect on cache operation performance, especially if partition
+ * awareness is used.
+ *
+ * Zero value means that number of active connections is not limited.
+ *
+ * The default value is zero.
+ *
+ * @return Active connection limit.
+ */
+ uint32_t GetConnectionsLimit() const
+ {
+ return connectionsLimit;
+ }
+
+ /**
+ * Set connection limit.
+ *
+ * @see GetConnectionsLimit for details.
+ *
+ * @param connectionsLimit Connections limit to set.
+ */
+ void SetConnectionsLimit(uint32_t limit)
+ {
+ connectionsLimit = limit;
+ }
+
private:
/** Connection end points */
std::string endPoints;
@@ -254,6 +286,9 @@ namespace ignite
/** Partition awareness. */
bool partitionAwareness;
+
+ /** Active connections limit. */
+ uint32_t connectionsLimit;
};
}
}
diff --git a/modules/platforms/cpp/thin-client/src/impl/data_router.cpp b/modules/platforms/cpp/thin-client/src/impl/data_router.cpp
index ea672ad..0943afa 100644
--- a/modules/platforms/cpp/thin-client/src/impl/data_router.cpp
+++ b/modules/platforms/cpp/thin-client/src/impl/data_router.cpp
@@ -111,6 +111,16 @@ namespace ignite
break;
}
}
+
+ if (config.GetConnectionsLimit())
+ {
+ common::concurrent::CsLockGuard lock(channelsMutex);
+
+ size_t connectionsNum = newLegacyChannels.size() + channels.size();
+
+ if (connectionsNum >= config.GetConnectionsLimit())
+ break;
+ }
}
common::concurrent::CsLockGuard lock(channelsMutex);