diff --git a/cpp/config/glacier2router.cfg b/cpp/config/glacier2router.cfg index 14d325fc2ff..56f7740686e 100644 --- a/cpp/config/glacier2router.cfg +++ b/cpp/config/glacier2router.cfg @@ -37,13 +37,6 @@ Glacier2.Server.Endpoints=tcp -h localhost # Glacier2.PermissionsVerifier=DemoGlacier2Router/NullPermissionsVerifier -# -# The timeout for inactive sessions. If any client session is inactive -# for longer than this value, the session expires and is removed. The -# unit is seconds. -# -Glacier2.SessionTimeout=30 - # # Glacier2 always disables active connection management so there is no # need to configure this manually. Connection retry does not need to diff --git a/cpp/config/templates.xml b/cpp/config/templates.xml index 79355bd7b3a..a8d238b3d9a 100644 --- a/cpp/config/templates.xml +++ b/cpp/config/templates.xml @@ -15,7 +15,6 @@ - diff --git a/cpp/include/Ice/Connection.h b/cpp/include/Ice/Connection.h index 8a0a9461ca4..437dcdc612a 100644 --- a/cpp/include/Ice/Connection.h +++ b/cpp/include/Ice/Connection.h @@ -46,87 +46,6 @@ namespace Ice BasedOnProxy }; - /** - * Specifies the close semantics for Active Connection Management. - */ - enum class ACMClose : std::uint8_t - { - /** - * Disables automatic connection closure. - */ - CloseOff, - /** - * Gracefully closes a connection that has been idle for the configured timeout period. - */ - CloseOnIdle, - /** - * Forcefully closes a connection that has been idle for the configured timeout period, but only if the - * connection has pending invocations. - */ - CloseOnInvocation, - /** - * Combines the behaviors of CloseOnIdle and CloseOnInvocation. - */ - CloseOnInvocationAndIdle, - /** - * Forcefully closes a connection that has been idle for the configured timeout period, regardless of whether - * the connection has pending invocations or dispatch. - */ - CloseOnIdleForceful - }; - - /** - * Specifies the heartbeat semantics for Active Connection Management. - */ - enum class ACMHeartbeat : std::uint8_t - { - /** - * Disables heartbeats. - */ - HeartbeatOff, - /** - * Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. - */ - HeartbeatOnDispatch, - /** - * Send a heartbeat at regular intervals when the connection is idle. - */ - HeartbeatOnIdle, - /** - * Send a heartbeat at regular intervals until the connection is closed. - */ - HeartbeatAlways - }; - - /** - * A collection of Active Connection Management configuration settings. - * \headerfile Ice/Ice.h - */ - struct ACM - { - /** - * A timeout value in seconds. - */ - int timeout; - /** - * The close semantics. - */ - ACMClose close; - /** - * The heartbeat semantics. - */ - ACMHeartbeat heartbeat; - - /** - * Obtains a tuple containing all of the struct's data members. - * @return The data members in a tuple. - */ - std::tuple ice_tuple() const - { - return std::tie(timeout, close, heartbeat); - } - }; - /** * Determines the behavior when manually closing a connection. */ @@ -338,23 +257,6 @@ namespace Ice */ std::future heartbeatAsync(); - /** - * Set the active connection management parameters. - * @param timeout The timeout value in seconds, must be >= 0. - * @param close The close condition - * @param heartbeat The heartbeat condition - */ - virtual void setACM( - const std::optional& timeout, - const std::optional& close, - const std::optional& heartbeat) = 0; - - /** - * Get the ACM parameters. - * @return The ACM parameters. - */ - virtual ACM getACM() noexcept = 0; - /** * Return the connection type. This corresponds to the endpoint type, i.e., "tcp", "udp", etc. * @return The type of the connection. diff --git a/cpp/msbuild/ice.test.sln b/cpp/msbuild/ice.test.sln index 0e4d43001ee..93007e496f4 100644 --- a/cpp/msbuild/ice.test.sln +++ b/cpp/msbuild/ice.test.sln @@ -3,24 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34330.188 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "..\test\Ice\acm\msbuild\client\client.vcxproj", "{CD25A05C-228D-473F-A86F-6C2DD22085B4}" - ProjectSection(ProjectDependencies) = postProject - {C7223CC8-0AAA-470B-ACB3-12B9DE75525C} = {C7223CC8-0AAA-470B-ACB3-12B9DE75525C} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Ice", "Ice", "{2CAF9731-CB18-498C-A3EF-24F3D8A334AC}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "acm", "acm", "{C6B8BC64-0F88-4C57-A12D-A43372141F67}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{2D52604F-E2AD-4586-BBD7-BD13536C702C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testcommon", "..\test\Common\msbuild\testcommon.vcxproj", "{C7223CC8-0AAA-470B-ACB3-12B9DE75525C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "..\test\Ice\acm\msbuild\server\server.vcxproj", "{FC4AC0A5-84D5-461F-BE52-EA686F52773E}" - ProjectSection(ProjectDependencies) = postProject - {C7223CC8-0AAA-470B-ACB3-12B9DE75525C} = {C7223CC8-0AAA-470B-ACB3-12B9DE75525C} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "adapterDeactivation", "adapterDeactivation", "{295C483A-8A84-4AEE-9F17-26B1A2422B2D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "client", "..\test\Ice\adapterDeactivation\msbuild\client\client.vcxproj", "{715411FA-34B3-4ABF-8476-3C84F5EFFFE5}" @@ -1144,14 +1132,6 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Debug|Win32.ActiveCfg = Debug|Win32 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Debug|Win32.Build.0 = Debug|Win32 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Debug|x64.ActiveCfg = Debug|x64 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Debug|x64.Build.0 = Debug|x64 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Release|Win32.ActiveCfg = Release|Win32 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Release|Win32.Build.0 = Release|Win32 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Release|x64.ActiveCfg = Release|x64 - {CD25A05C-228D-473F-A86F-6C2DD22085B4}.Release|x64.Build.0 = Release|x64 {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Debug|Win32.ActiveCfg = Debug|Win32 {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Debug|Win32.Build.0 = Debug|Win32 {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Debug|x64.ActiveCfg = Debug|x64 @@ -1160,14 +1140,6 @@ Global {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Release|Win32.Build.0 = Release|Win32 {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Release|x64.ActiveCfg = Release|x64 {C7223CC8-0AAA-470B-ACB3-12B9DE75525C}.Release|x64.Build.0 = Release|x64 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Debug|Win32.ActiveCfg = Debug|Win32 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Debug|Win32.Build.0 = Debug|Win32 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Debug|x64.ActiveCfg = Debug|x64 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Debug|x64.Build.0 = Debug|x64 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Release|Win32.ActiveCfg = Release|Win32 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Release|Win32.Build.0 = Release|Win32 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Release|x64.ActiveCfg = Release|x64 - {FC4AC0A5-84D5-461F-BE52-EA686F52773E}.Release|x64.Build.0 = Release|x64 {715411FA-34B3-4ABF-8476-3C84F5EFFFE5}.Debug|Win32.ActiveCfg = Debug|Win32 {715411FA-34B3-4ABF-8476-3C84F5EFFFE5}.Debug|Win32.Build.0 = Debug|Win32 {715411FA-34B3-4ABF-8476-3C84F5EFFFE5}.Debug|x64.ActiveCfg = Debug|x64 @@ -2653,10 +2625,7 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {CD25A05C-228D-473F-A86F-6C2DD22085B4} = {C6B8BC64-0F88-4C57-A12D-A43372141F67} - {C6B8BC64-0F88-4C57-A12D-A43372141F67} = {2CAF9731-CB18-498C-A3EF-24F3D8A334AC} {C7223CC8-0AAA-470B-ACB3-12B9DE75525C} = {2D52604F-E2AD-4586-BBD7-BD13536C702C} - {FC4AC0A5-84D5-461F-BE52-EA686F52773E} = {C6B8BC64-0F88-4C57-A12D-A43372141F67} {295C483A-8A84-4AEE-9F17-26B1A2422B2D} = {2CAF9731-CB18-498C-A3EF-24F3D8A334AC} {715411FA-34B3-4ABF-8476-3C84F5EFFFE5} = {295C483A-8A84-4AEE-9F17-26B1A2422B2D} {5D38E70A-98C1-4B1D-BC0D-01BC114078C5} = {295C483A-8A84-4AEE-9F17-26B1A2422B2D} diff --git a/cpp/src/Glacier2/Glacier2Router.cpp b/cpp/src/Glacier2/Glacier2Router.cpp index 2a3e235e0a5..535d0399678 100644 --- a/cpp/src/Glacier2/Glacier2Router.cpp +++ b/cpp/src/Glacier2/Glacier2Router.cpp @@ -141,11 +141,6 @@ RouterService::start(int argc, char* argv[], int& status) return false; } - if (properties->getProperty("Glacier2.Client.ACM.Close").empty()) - { - properties->setProperty("Glacier2.Client.ACM.Close", "4"); // Forcefull close on invocation and idle. - } - auto clientAdapter = communicator()->createObjectAdapter("Glacier2.Client"); // @@ -450,22 +445,11 @@ RouterService::initializeCommunicator( } } - // - // Active connection management is permitted with Glacier2. For - // the client object adapter, the ACM timeout is set to the - // session timeout to ensure client connections are not closed - // prematurely, - // - // initData.properties->setProperty("Ice.ACM.Client", "0"); - // initData.properties->setProperty("Ice.ACM.Server", "0"); - - // // We do not need to set Ice.RetryIntervals to -1, i.e., we do // not have to disable connection retry. It is safe for // Glacier2 to retry outgoing connections to servers. Retry // for incoming connections from clients must be disabled in // the clients. - // return Service::initializeCommunicator(argc, argv, initData, version); } diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp index d31709d4747..1dee81b1822 100644 --- a/cpp/src/Glacier2/SessionRouterI.cpp +++ b/cpp/src/Glacier2/SessionRouterI.cpp @@ -824,13 +824,15 @@ SessionRouterI::destroySession(const ConnectionPtr& connection) int64_t SessionRouterI::getSessionTimeout(const Ice::Current& current) const { - return current.con->getACM().timeout; + return getACMTimeout(current); } int -SessionRouterI::getACMTimeout(const Ice::Current& current) const +SessionRouterI::getACMTimeout(const Ice::Current&) const { - return current.con->getACM().timeout; + // TODO: better way to retrieve idle timeout + int idleTimeout = _instance->properties()->getPropertyAsIntWithDefault("Ice.Connection.IdleTimeout", 60); + return _instance->properties()->getPropertyAsIntWithDefault("Glacier2.Client.Connection.IdleTimeout", idleTimeout); } void diff --git a/cpp/src/Glacier2Lib/SessionHelper.cpp b/cpp/src/Glacier2Lib/SessionHelper.cpp index 1a8eba0fb58..a07acf47d8f 100644 --- a/cpp/src/Glacier2Lib/SessionHelper.cpp +++ b/cpp/src/Glacier2Lib/SessionHelper.cpp @@ -450,20 +450,22 @@ SessionHelperI::connected(const Glacier2::RouterPrx& router, const optionalice_getCachedConnection(); string category = router->getCategoryForClient(); - int32_t acmTimeout = 0; + int32_t remoteIdleTimeout = 0; try { - acmTimeout = router->getACMTimeout(); + remoteIdleTimeout = router->getACMTimeout(); } catch (const Ice::OperationNotExistException&) { } - if (acmTimeout <= 0) + if (remoteIdleTimeout <= 0) { - acmTimeout = static_cast(router->getSessionTimeout()); + remoteIdleTimeout = static_cast(router->getSessionTimeout()); } + // TODO: verify remote idle timeout is compatible with local idle timeout + // // We create the callback object adapter here because createObjectAdapter internally // makes synchronous RPCs to the router. We can't create the OA on-demand when the @@ -495,14 +497,9 @@ SessionHelperI::connected(const Glacier2::RouterPrx& router, const optional 0) - { - Ice::ConnectionPtr connection = _router->ice_getCachedConnection(); - assert(connection); - connection->setACM(acmTimeout, nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - auto self = shared_from_this(); - connection->setCloseCallback([self](Ice::ConnectionPtr) { self->destroy(); }); - } + Ice::ConnectionPtr connection = _router->ice_getCachedConnection(); + assert(connection); + connection->setCloseCallback([self = shared_from_this()](Ice::ConnectionPtr) { self->destroy(); }); } } diff --git a/cpp/src/Ice/ACM.cpp b/cpp/src/Ice/ACM.cpp deleted file mode 100644 index 1301d668ce8..00000000000 --- a/cpp/src/Ice/ACM.cpp +++ /dev/null @@ -1,377 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include "ACM.h" -#include "ConnectionI.h" -#include "Ice/LocalException.h" -#include "Ice/LoggerUtil.h" -#include "Ice/Properties.h" -#include "Instance.h" - -using namespace std; -using namespace Ice; -using namespace IceInternal; - -IceInternal::ACMConfig::ACMConfig(bool server) - : timeout(chrono::seconds(60)), - heartbeat(ACMHeartbeat::HeartbeatOnDispatch), - close(server ? ACMClose::CloseOnInvocation : ACMClose::CloseOnInvocationAndIdle) -{ -} - -IceInternal::ACMConfig::ACMConfig( - const Ice::PropertiesPtr& p, - const Ice::LoggerPtr& l, - const string& prefix, - const ACMConfig& dflt) -{ - string timeoutProperty; - if ((prefix == "Ice.ACM.Client" || prefix == "Ice.ACM.Server") && p->getProperty(prefix + ".Timeout").empty()) - { - timeoutProperty = prefix; // Deprecated property. - } - else - { - timeoutProperty = prefix + ".Timeout"; - } - - int timeoutVal = p->getPropertyAsIntWithDefault(timeoutProperty, static_cast(dflt.timeout.count())); - if (timeoutVal >= 0) - { - timeout = chrono::seconds(timeoutVal); - } - else - { - l->warning("invalid value for property `" + timeoutProperty + "', default value will be used instead"); - timeout = dflt.timeout; - } - - int hb = p->getPropertyAsIntWithDefault(prefix + ".Heartbeat", static_cast(dflt.heartbeat)); - if (hb >= static_cast(ACMHeartbeat::HeartbeatOff) && hb <= static_cast(ACMHeartbeat::HeartbeatAlways)) - { - heartbeat = static_cast(hb); - } - else - { - l->warning("invalid value for property `" + prefix + ".Heartbeat" + "', default value will be used instead"); - heartbeat = dflt.heartbeat; - } - - int cl = p->getPropertyAsIntWithDefault(prefix + ".Close", static_cast(dflt.close)); - if (cl >= static_cast(ACMClose::CloseOff) && cl <= static_cast(ACMClose::CloseOnIdleForceful)) - { - close = static_cast(cl); - } - else - { - l->warning("invalid value for property `" + prefix + ".Close" + "', default value will be used instead"); - close = dflt.close; - } -} - -IceInternal::FactoryACMMonitor::FactoryACMMonitor(const InstancePtr& instance, const ACMConfig& config) - : _instance(instance), - _config(config) -{ -} - -IceInternal::FactoryACMMonitor::~FactoryACMMonitor() -{ - assert(!_instance); - assert(_connections.empty()); - assert(_changes.empty()); - assert(_reapedConnections.empty()); -} - -void -IceInternal::FactoryACMMonitor::destroy() -{ - unique_lock lock(_mutex); - if (!_instance) - { - // - // Ensure all the connections have been cleared, it's important to wait here - // to prevent the timer destruction in IceInternal::Instance::destroy. - // - _conditionVariable.wait(lock, [this] { return _connections.empty(); }); - return; - } - - // - // Cancel the scheduled timer task and schedule it again now to clear the - // connection set from the timer thread. - // - if (!_connections.empty()) - { - _instance->timer()->cancel(shared_from_this()); - _instance->timer()->schedule(shared_from_this(), chrono::seconds::zero()); - } - - _instance = 0; - _changes.clear(); - - // - // Wait for the connection set to be cleared by the timer thread. - // - _conditionVariable.wait(lock, [this] { return _connections.empty(); }); -} - -void -IceInternal::FactoryACMMonitor::add(const ConnectionIPtr& connection) -{ - if (_config.timeout == chrono::seconds::zero()) - { - return; - } - - lock_guard lock(_mutex); - if (_connections.empty()) - { - _connections.insert(connection); - // We convert to milliseconds in case the timeout is only one or a few seconds; the division is an integral - // division. - _instance->timer()->scheduleRepeated( - shared_from_this(), - chrono::duration_cast(_config.timeout) / 2); - } - else - { - _changes.push_back(make_pair(connection, true)); - } -} - -void -IceInternal::FactoryACMMonitor::remove(const ConnectionIPtr& connection) -{ - if (_config.timeout == chrono::seconds::zero()) - { - return; - } - - lock_guard lock(_mutex); - assert(_instance); - _changes.push_back(make_pair(connection, false)); -} - -void -IceInternal::FactoryACMMonitor::reap(const ConnectionIPtr& connection) -{ - lock_guard lock(_mutex); - _reapedConnections.push_back(connection); -} - -ACMMonitorPtr -IceInternal::FactoryACMMonitor::acm( - const optional& timeout, - const optional& close, - const optional& heartbeat) -{ - lock_guard lock(_mutex); - assert(_instance); - - ACMConfig config(_config); - if (timeout) - { - config.timeout = chrono::seconds(*timeout); - } - if (close) - { - config.close = *close; - } - if (heartbeat) - { - config.heartbeat = *heartbeat; - } - return make_shared(shared_from_this(), _instance->timer(), config); -} - -Ice::ACM -IceInternal::FactoryACMMonitor::getACM() -{ - Ice::ACM acm; - acm.timeout = static_cast(_config.timeout.count()); - acm.close = _config.close; - acm.heartbeat = _config.heartbeat; - return acm; -} - -void -IceInternal::FactoryACMMonitor::swapReapedConnections(vector& connections) -{ - lock_guard lock(_mutex); - _reapedConnections.swap(connections); -} - -void -IceInternal::FactoryACMMonitor::runTimerTask() -{ - { - lock_guard lock(_mutex); - if (!_instance) - { - _connections.clear(); - _conditionVariable.notify_all(); - return; - } - - for (vector>::const_iterator p = _changes.begin(); p != _changes.end(); ++p) - { - if (p->second) - { - _connections.insert(p->first); - } - else - { - _connections.erase(p->first); - } - } - _changes.clear(); - - if (_connections.empty()) - { - _instance->timer()->cancel(shared_from_this()); - return; - } - } - - // - // Monitor connections outside the thread synchronization, so - // that connections can be added or removed during monitoring. - // - auto now = chrono::steady_clock::now(); - for (set::const_iterator p = _connections.begin(); p != _connections.end(); ++p) - { - try - { - (*p)->monitor(now, _config); - } - catch (const exception& ex) - { - handleException(ex); - } - catch (...) - { - handleException(); - } - } -} - -void -FactoryACMMonitor::handleException(const exception& ex) -{ - lock_guard lock(_mutex); - if (!_instance) - { - return; - } - - Error out(_instance->initializationData().logger); - out << "exception in connection monitor:\n" << ex.what(); -} - -void -FactoryACMMonitor::handleException() -{ - lock_guard lock(_mutex); - if (!_instance) - { - return; - } - - Error out(_instance->initializationData().logger); - out << "unknown exception in connection monitor"; -} - -IceInternal::ConnectionACMMonitor::ConnectionACMMonitor( - const FactoryACMMonitorPtr& parent, - const IceUtil::TimerPtr& timer, - const ACMConfig& config) - : _parent(parent), - _timer(timer), - _config(config) -{ -} - -IceInternal::ConnectionACMMonitor::~ConnectionACMMonitor() { assert(!_connection); } - -void -IceInternal::ConnectionACMMonitor::add(const ConnectionIPtr& connection) -{ - lock_guard lock(_mutex); - assert(!_connection && connection); - _connection = connection; - if (_config.timeout != chrono::seconds::zero()) - { - // We convert to milliseconds in case the timeout is only one or a few seconds; the division is an integral - // division. - _timer->scheduleRepeated(shared_from_this(), chrono::duration_cast(_config.timeout) / 2); - } -} - -void -IceInternal::ConnectionACMMonitor::remove([[maybe_unused]] const ConnectionIPtr& connection) -{ -#ifdef _MSC_VER - UNREFERENCED_PARAMETER(connection); -#endif - lock_guard lock(_mutex); - assert(_connection == connection); - if (_config.timeout != chrono::seconds::zero()) - { - _timer->cancel(shared_from_this()); - } - _connection = 0; -} - -void -IceInternal::ConnectionACMMonitor::reap(const ConnectionIPtr& connection) -{ - _parent->reap(connection); -} - -ACMMonitorPtr -IceInternal::ConnectionACMMonitor::acm( - const optional& timeout, - const optional& close, - const optional& heartbeat) -{ - return _parent->acm(timeout, close, heartbeat); -} - -Ice::ACM -IceInternal::ConnectionACMMonitor::getACM() -{ - Ice::ACM acm; - acm.timeout = static_cast(_config.timeout.count()); - acm.close = _config.close; - acm.heartbeat = _config.heartbeat; - return acm; -} - -void -IceInternal::ConnectionACMMonitor::runTimerTask() -{ - Ice::ConnectionIPtr connection; - { - lock_guard lock(_mutex); - if (!_connection) - { - return; - } - connection = _connection; - } - - try - { - connection->monitor(chrono::steady_clock::now(), _config); - } - catch (const exception& ex) - { - _parent->handleException(ex); - } - catch (...) - { - _parent->handleException(); - } -} diff --git a/cpp/src/Ice/ACM.h b/cpp/src/Ice/ACM.h deleted file mode 100644 index edb7d6a4695..00000000000 --- a/cpp/src/Ice/ACM.h +++ /dev/null @@ -1,112 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#ifndef ICE_ACM_H -#define ICE_ACM_H - -#include "ACMF.h" -#include "Ice/Connection.h" -#include "Ice/ConnectionIF.h" -#include "Ice/InstanceF.h" -#include "Ice/Logger.h" -#include "Ice/PropertiesF.h" -#include "IceUtil/Timer.h" - -#include -#include -#include -#include - -namespace IceInternal -{ - class ACMConfig - { - public: - ACMConfig(bool = false); - ACMConfig(const Ice::PropertiesPtr&, const Ice::LoggerPtr&, const std::string&, const ACMConfig&); - - std::chrono::seconds timeout; - Ice::ACMHeartbeat heartbeat; - Ice::ACMClose close; - }; - - class ACMMonitor : public IceUtil::TimerTask - { - public: - virtual void add(const Ice::ConnectionIPtr&) = 0; - virtual void remove(const Ice::ConnectionIPtr&) = 0; - virtual void reap(const Ice::ConnectionIPtr&) = 0; - - virtual ACMMonitorPtr - acm(const std::optional&, - const std::optional&, - const std::optional&) = 0; - virtual Ice::ACM getACM() = 0; - }; - - class FactoryACMMonitor final : public ACMMonitor, public std::enable_shared_from_this - { - public: - FactoryACMMonitor(const InstancePtr&, const ACMConfig&); - ~FactoryACMMonitor() final; - - void add(const Ice::ConnectionIPtr&) final; - void remove(const Ice::ConnectionIPtr&) final; - void reap(const Ice::ConnectionIPtr&) final; - - ACMMonitorPtr - acm(const std::optional&, - const std::optional&, - const std::optional&) final; - Ice::ACM getACM() final; - - void destroy(); - void swapReapedConnections(std::vector&); - - private: - friend class ConnectionACMMonitor; - void handleException(const std::exception&); - void handleException(); - - void runTimerTask() final; - - InstancePtr _instance; - const ACMConfig _config; - - std::vector> _changes; - std::set _connections; - std::vector _reapedConnections; - std::mutex _mutex; - std::condition_variable _conditionVariable; - }; - - class ConnectionACMMonitor final : public ACMMonitor, public std::enable_shared_from_this - { - public: - ConnectionACMMonitor(const FactoryACMMonitorPtr&, const IceUtil::TimerPtr&, const ACMConfig&); - ~ConnectionACMMonitor() final; - - void add(const Ice::ConnectionIPtr&) final; - void remove(const Ice::ConnectionIPtr&) final; - void reap(const Ice::ConnectionIPtr&) final; - - ACMMonitorPtr - acm(const std::optional&, - const std::optional&, - const std::optional&) final; - Ice::ACM getACM() final; - - private: - void runTimerTask() final; - - const FactoryACMMonitorPtr _parent; - const IceUtil::TimerPtr _timer; - const ACMConfig _config; - - Ice::ConnectionIPtr _connection; - std::mutex _mutex; - }; -} - -#endif diff --git a/cpp/src/Ice/ACMF.h b/cpp/src/Ice/ACMF.h deleted file mode 100644 index 65abe93c05b..00000000000 --- a/cpp/src/Ice/ACMF.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#ifndef ICE_ACM_F_H -#define ICE_ACM_F_H - -#include - -namespace IceInternal -{ - class ACMMonitor; - class FactoryACMMonitor; - - using ACMMonitorPtr = std::shared_ptr; - using FactoryACMMonitorPtr = std::shared_ptr; -} - -#endif diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp index 9b5e23e7f9d..ddf2ce4e3f2 100644 --- a/cpp/src/Ice/ConnectionFactory.cpp +++ b/cpp/src/Ice/ConnectionFactory.cpp @@ -169,27 +169,16 @@ IceInternal::OutgoingConnectionFactory::waitUntilFinished() connections = _connections; } - for (const auto& p : _connections) + for (const auto& p : connections) { p.second->waitUntilFinished(); } { lock_guard lock(_mutex); - // Ensure all the connections are finished and reapable at this point. - vector cons; - _monitor->swapReapedConnections(cons); - assert(cons.size() == _connections.size()); - cons.clear(); _connections.clear(); _connectionsByEndpoint.clear(); } - - // - // Must be destroyed outside the synchronization since this might block waiting for - // a timer task to complete. - // - _monitor->destroy(); } void @@ -342,12 +331,23 @@ IceInternal::OutgoingConnectionFactory::flushAsyncBatchRequests( } } +void +IceInternal::OutgoingConnectionFactory::removeConnection(const ConnectionIPtr& connection) noexcept +{ + lock_guard lock(_mutex); + if (!_destroyed) + { + remove(_connections, connection->connector(), connection); + remove(_connectionsByEndpoint, connection->endpoint(), connection); + remove(_connectionsByEndpoint, connection->endpoint()->compress(true), connection); + } +} + IceInternal::OutgoingConnectionFactory::OutgoingConnectionFactory( const CommunicatorPtr& communicator, const InstancePtr& instance) : _communicator(communicator), _instance(instance), - _monitor(new FactoryACMMonitor(instance, instance->clientACM())), _connectionOptions(instance->clientConnectionOptions()), _destroyed(false), _pendingConnectCount(0) @@ -489,18 +489,6 @@ IceInternal::OutgoingConnectionFactory::getConnection( throw Ice::CommunicatorDestroyedException(__FILE__, __LINE__); } - // - // Reap closed connections - // - vector cons; - _monitor->swapReapedConnections(cons); - for (const auto& p : cons) - { - remove(_connections, p->connector(), p); - remove(_connectionsByEndpoint, p->endpoint(), p); - remove(_connectionsByEndpoint, p->endpoint()->compress(true), p); - } - // // Try to get the connection. We may need to wait for other threads to // finish if one of them is currently establishing a connection to one @@ -593,11 +581,17 @@ IceInternal::OutgoingConnectionFactory::createConnection(const TransceiverPtr& t connection = ConnectionI::create( _communicator, _instance, - _monitor, transceiver, ci.connector, ci.endpoint->compress(false), nullptr, + [weakSelf = weak_from_this()](const ConnectionIPtr& closedConnection) + { + if (auto self = weakSelf.lock()) + { + self->removeConnection(closedConnection); + } + }, _connectionOptions); } catch (const Ice::LocalException&) @@ -1266,26 +1260,8 @@ IceInternal::IncomingConnectionFactory::waitUntilFinished() { lock_guard lock(_mutex); - if (_transceiver) - { - assert(_connections.size() <= 1); // The connection isn't monitored or reaped. - } - else - { - // Ensure all the connections are finished and reapable at this point. - vector cons; - _monitor->swapReapedConnections(cons); - assert(cons.size() == _connections.size()); - cons.clear(); - } _connections.clear(); } - - // - // Must be destroyed outside the synchronization since this might block waiting for - // a timer task to complete. - // - _monitor->destroy(); } bool @@ -1328,6 +1304,17 @@ IceInternal::IncomingConnectionFactory::connections() const return result; } +void +IceInternal::IncomingConnectionFactory::removeConnection(const ConnectionIPtr& connection) noexcept +{ + lock_guard lock(_mutex); + if (_state == StateActive || _state == StateHolding) + { + _connections.erase(connection); + } + // else it's already being cleaned up. +} + void IceInternal::IncomingConnectionFactory::flushAsyncBatchRequests( const CommunicatorFlushBatchAsyncPtr& outAsync, @@ -1427,16 +1414,6 @@ IceInternal::IncomingConnectionFactory::message(ThreadPoolCurrent& current) return; } - // - // Reap closed connections - // - vector cons; - _monitor->swapReapedConnections(cons); - for (vector::const_iterator p = cons.begin(); p != cons.end(); ++p) - { - _connections.erase(*p); - } - if (!_acceptorStarted) { return; @@ -1492,11 +1469,17 @@ IceInternal::IncomingConnectionFactory::message(ThreadPoolCurrent& current) connection = ConnectionI::create( _adapter->getCommunicator(), _instance, - _monitor, transceiver, nullptr, // connector _endpoint, _adapter, + [weakSelf = weak_from_this()](const ConnectionIPtr& closedConnection) + { + if (auto self = weakSelf.lock()) + { + static_pointer_cast(self)->removeConnection(closedConnection); + } + }, _connectionOptions); } catch (const LocalException& ex) @@ -1648,7 +1631,6 @@ IceInternal::IncomingConnectionFactory::IncomingConnectionFactory( const EndpointIPtr& publishedEndpoint, const shared_ptr& adapter) : _instance(instance), - _monitor(new FactoryACMMonitor(instance, dynamic_cast(adapter.get())->getACM())), _connectionOptions(instance->serverConnectionOptions(adapter->getName())), _endpoint(endpoint), _publishedEndpoint(publishedEndpoint), @@ -1719,11 +1701,11 @@ IceInternal::IncomingConnectionFactory::initialize() ConnectionIPtr connection(ConnectionI::create( _adapter->getCommunicator(), _instance, - nullptr, _transceiver, nullptr, _endpoint, _adapter, + nullptr, _connectionOptions)); connection->startAsync(nullptr, nullptr); _connections.insert(connection); @@ -1756,7 +1738,6 @@ IceInternal::IncomingConnectionFactory::initialize() } _state = StateFinished; - _monitor->destroy(); _connections.clear(); throw; } diff --git a/cpp/src/Ice/ConnectionFactory.h b/cpp/src/Ice/ConnectionFactory.h index afdb4c998fb..427c8d9f760 100644 --- a/cpp/src/Ice/ConnectionFactory.h +++ b/cpp/src/Ice/ConnectionFactory.h @@ -5,7 +5,6 @@ #ifndef ICE_CONNECTION_FACTORY_H #define ICE_CONNECTION_FACTORY_H -#include "ACMF.h" #include "AcceptorF.h" #include "ConnectionFactoryF.h" #include "ConnectionI.h" @@ -61,6 +60,8 @@ namespace IceInternal void removeAdapter(const Ice::ObjectAdapterPtr&); void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, Ice::CompressBatch); + void removeConnection(const Ice::ConnectionIPtr&) noexcept; + OutgoingConnectionFactory(const Ice::CommunicatorPtr&, const InstancePtr&); ~OutgoingConnectionFactory(); friend class Instance; @@ -148,7 +149,6 @@ namespace IceInternal Ice::CommunicatorPtr _communicator; const InstancePtr _instance; - const FactoryACMMonitorPtr _monitor; const Ice::ConnectionOptions _connectionOptions; bool _destroyed; @@ -188,6 +188,8 @@ namespace IceInternal bool isLocal(const EndpointIPtr&) const; EndpointIPtr endpoint() const; std::list connections() const; + void removeConnection(const Ice::ConnectionIPtr&) noexcept; + void flushAsyncBatchRequests(const CommunicatorFlushBatchAsyncPtr&, Ice::CompressBatch); // @@ -234,7 +236,6 @@ namespace IceInternal void closeAcceptor(); const InstancePtr _instance; - const FactoryACMMonitorPtr _monitor; const Ice::ConnectionOptions _connectionOptions; AcceptorPtr _acceptor; diff --git a/cpp/src/Ice/ConnectionI.cpp b/cpp/src/Ice/ConnectionI.cpp index a8704a428fe..016bbf9dddc 100644 --- a/cpp/src/Ice/ConnectionI.cpp +++ b/cpp/src/Ice/ConnectionI.cpp @@ -3,7 +3,6 @@ // #include "ConnectionI.h" -#include "ACM.h" #include "BatchRequestQueue.h" #include "CheckIdentity.h" #include "DefaultsAndOverrides.h" @@ -472,10 +471,6 @@ Ice::ConnectionI::activate() { return; } - if (_acmLastActivity != chrono::steady_clock::time_point()) - { - _acmLastActivity = chrono::steady_clock::now(); - } setState(StateActive); } @@ -633,72 +628,6 @@ Ice::ConnectionI::updateObserver() _observer.attach(o); } -void -Ice::ConnectionI::monitor(const chrono::steady_clock::time_point& now, const ACMConfig& acm) -{ - lock_guard lock(_mutex); - if (_state != StateActive) - { - return; - } - assert(acm.timeout != chrono::seconds::zero()); - - // - // We send a heartbeat if there was no activity in the last - // (timeout / 4) period. Sending a heartbeat sooner than really - // needed is safer to ensure that the receiver will receive the - // heartbeat in time. Sending the heartbeat if there was no - // activity in the last (timeout / 2) period isn't enough since - // monitor() is called only every (timeout / 2) period. - // - // Note that this doesn't imply that we are sending 4 heartbeats - // per timeout period because the monitor() method is still only - // called every (timeout / 2) period. - // - if (acm.heartbeat == ACMHeartbeat::HeartbeatAlways || - (acm.heartbeat != ACMHeartbeat::HeartbeatOff && _writeStream.b.empty() && - now >= (_acmLastActivity + chrono::duration_cast(acm.timeout) / 4))) - { - if (acm.heartbeat != ACMHeartbeat::HeartbeatOnDispatch || _upcallCount > 0) - { - sendHeartbeatNow(); - } - } - - if (static_cast(_readStream.b.size()) > headerSize || !_writeStream.b.empty()) - { - // - // If writing or reading, nothing to do, the connection - // timeout will kick-in if writes or reads don't progress. - // This check is necessary because the activity timer is - // only set when a message is fully read/written. - // - return; - } - - if (acm.close != ACMClose::CloseOff && now >= (_acmLastActivity + acm.timeout)) - { - if (acm.close == ACMClose::CloseOnIdleForceful || - (acm.close != ACMClose::CloseOnIdle && !_asyncRequests.empty())) - { - // - // Close the connection if we didn't receive a heartbeat in - // the last period. - // - setState(StateClosed, make_exception_ptr(ConnectionTimeoutException(__FILE__, __LINE__))); - } - else if ( - acm.close != ACMClose::CloseOnInvocation && _upcallCount == 0 && _batchRequestQueue->isEmpty() && - _asyncRequests.empty()) - { - // - // The connection is idle, close it. - // - setState(StateClosing, make_exception_ptr(ConnectionTimeoutException(__FILE__, __LINE__))); - } - } -} - AsyncStatus Ice::ConnectionI::sendAsyncRequest(const OutgoingAsyncBasePtr& out, bool compress, bool response, int batchRequestCount) { @@ -964,54 +893,6 @@ Ice::ConnectionI::closeCallback(const CloseCallback& callback) } } -void -Ice::ConnectionI::setACM( - const optional& timeout, - const optional& close, - const optional& heartbeat) -{ - std::lock_guard lock(_mutex); - if (timeout && *timeout < 0) - { - throw invalid_argument("invalid negative ACM timeout value"); - } - if (!_monitor || _state >= StateClosed) - { - return; - } - - if (_state == StateActive) - { - _monitor->remove(shared_from_this()); - } - _monitor = _monitor->acm(timeout, close, heartbeat); - - if (_monitor->getACM().timeout <= 0) - { - _acmLastActivity = chrono::steady_clock::time_point(); // Disable the recording of last activity. - } - else if (_acmLastActivity == chrono::steady_clock::time_point() && _state == StateActive) - { - _acmLastActivity = chrono::steady_clock::now(); - } - - if (_state == StateActive) - { - _monitor->add(shared_from_this()); - } -} - -ACM -Ice::ConnectionI::getACM() noexcept -{ - std::lock_guard lock(_mutex); - ACM acm; - acm.timeout = 0; - acm.close = ACMClose::CloseOff; - acm.heartbeat = ACMHeartbeat::HeartbeatOff; - return _monitor ? _monitor->getACM() : acm; -} - void Ice::ConnectionI::asyncRequestCanceled(const OutgoingAsyncBasePtr& outAsync, exception_ptr ex) { @@ -1135,22 +1016,33 @@ Ice::ConnectionI::dispatchException(exception_ptr ex, int requestCount) // Fatal exception while dispatching a request. Since sendResponse isn't called in case of a fatal exception we // decrement _upcallCount here. - std::lock_guard lock(_mutex); - setState(StateClosed, ex); - - if (requestCount > 0) + bool finished = false; { - assert(_upcallCount >= requestCount); - _upcallCount -= requestCount; - if (_upcallCount == 0) + std::lock_guard lock(_mutex); + setState(StateClosed, ex); + + if (requestCount > 0) { - if (_state == StateFinished) + assert(_upcallCount >= requestCount); + _upcallCount -= requestCount; + if (_upcallCount == 0) { - reap(); + if (_state == StateFinished) + { + finished = true; + if (_observer) + { + _observer.detach(); + } + } + _conditionVariable.notify_all(); } - _conditionVariable.notify_all(); } } + if (finished) + { + _removeFromFactory(shared_from_this()); + } } EndpointIPtr @@ -1572,11 +1464,6 @@ Ice::ConnectionI::message(ThreadPoolCurrent& current) } } - if (_acmLastActivity != chrono::steady_clock::time_point()) - { - _acmLastActivity = chrono::steady_clock::now(); - } - if (upcallCount == 0) { return; // Nothing to dispatch we're done! @@ -1762,6 +1649,7 @@ ConnectionI::upcall( // // Decrease the upcall count. // + bool finished = false; if (completedUpcallCount > 0) { std::lock_guard lock(_mutex); @@ -1783,11 +1671,19 @@ ConnectionI::upcall( } else if (_state == StateFinished) { - reap(); + finished = true; + if (_observer) + { + _observer.detach(); + } } _conditionVariable.notify_all(); } } + if (finished) + { + _removeFromFactory(shared_from_this()); + } } void @@ -1970,19 +1866,26 @@ Ice::ConnectionI::finish(bool close) _heartbeatCallback = nullptr; - // // This must be done last as this will cause waitUntilFinished() to return (and communicator // objects such as the timer might be destroyed too). - // + bool finished = false; { std::lock_guard lock(_mutex); setState(StateFinished); if (_upcallCount == 0) { - reap(); + finished = true; + if (_observer) + { + _observer.detach(); + } } } + if (finished) + { + _removeFromFactory(shared_from_this()); + } } string @@ -2042,15 +1945,14 @@ Ice::ConnectionI::exception(std::exception_ptr ex) Ice::ConnectionI::ConnectionI( const CommunicatorPtr& communicator, const InstancePtr& instance, - const ACMMonitorPtr& monitor, const TransceiverPtr& transceiver, const ConnectorPtr& connector, const EndpointIPtr& endpoint, const shared_ptr& adapter, + std::function removeFromFactory, const ConnectionOptions& options) noexcept : _communicator(communicator), _instance(instance), - _monitor(monitor), _transceiver(transceiver), _desc(transceiver->toString()), _type(transceiver->protocol()), @@ -2064,6 +1966,7 @@ Ice::ConnectionI::ConnectionI( _connectTimeout(options.connectTimeout), _closeTimeout(options.closeTimeout), _inactivityTimeout(options.inactivityTimeout), + _removeFromFactory(std::move(removeFromFactory)), _warn(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Connections") > 0), _warnUdp(_instance->initializationData().properties->getPropertyAsInt("Ice.Warn.Datagrams") > 0), _compressionLevel(1), @@ -2092,22 +1995,17 @@ Ice::ConnectionI::ConnectionI( { compressionLevel = 9; } - - if (_monitor && _monitor->getACM().timeout > 0) - { - _acmLastActivity = chrono::steady_clock::now(); - } } Ice::ConnectionIPtr Ice::ConnectionI::create( const CommunicatorPtr& communicator, const InstancePtr& instance, - const ACMMonitorPtr& monitor, const TransceiverPtr& transceiver, const ConnectorPtr& connector, const EndpointIPtr& endpoint, const shared_ptr& adapter, + std::function removeFromFactory, const ConnectionOptions& options) { shared_ptr decoratedTransceiver; @@ -2123,11 +2021,11 @@ Ice::ConnectionI::create( Ice::ConnectionIPtr connection(new ConnectionI( communicator, instance, - monitor, decoratedTransceiver ? decoratedTransceiver : transceiver, connector, endpoint, adapter, + std::move(removeFromFactory), options)); if (decoratedTransceiver) @@ -2354,28 +2252,6 @@ Ice::ConnectionI::setState(State state) out << "unexpected connection exception:\n" << ex << '\n' << _desc; } - // - // We only register with the connection monitor if our new state - // is StateActive. Otherwise we unregister with the connection - // monitor, but only if we were registered before, i.e., if our - // old state was StateActive. - // - if (_monitor) - { - if (state == StateActive) - { - if (_acmLastActivity != chrono::steady_clock::time_point()) - { - _acmLastActivity = chrono::steady_clock::now(); - } - _monitor->add(shared_from_this()); - } - else if (_state == StateActive) - { - _monitor->remove(shared_from_this()); - } - } - if (_instance->initializationData().observer) { ConnectionState oldState = toConnectionState(_state); @@ -2599,6 +2475,7 @@ Ice::ConnectionI::sendResponse(OutgoingResponse response, uint8_t compress) { bool isTwoWay = !_endpoint->datagram() && response.current().requestId != 0; + bool finished = false; try { std::unique_lock lock(_mutex); @@ -2610,16 +2487,29 @@ Ice::ConnectionI::sendResponse(OutgoingResponse response, uint8_t compress) { if (_state == StateFinished) { - reap(); + finished = true; + if (_observer) + { + _observer.detach(); + } } _conditionVariable.notify_all(); } if (_state >= StateClosed) { - assert(_exception); - rethrow_exception(_exception); + exception_ptr exception = _exception; + assert(exception); + + if (finished) + { + lock.unlock(); + _removeFromFactory(shared_from_this()); + } + + rethrow_exception(exception); } + assert(!finished); if (isTwoWay) { @@ -3007,10 +2897,6 @@ Ice::ConnectionI::sendMessage(OutgoingMessage& message) { status = static_cast(status | AsyncStatusInvokeSentCallback); } - if (_acmLastActivity != chrono::steady_clock::time_point()) - { - _acmLastActivity = chrono::steady_clock::now(); - } return status; } @@ -3064,10 +2950,6 @@ Ice::ConnectionI::sendMessage(OutgoingMessage& message) { status = static_cast(status | AsyncStatusInvokeSentCallback); } - if (_acmLastActivity != chrono::steady_clock::time_point()) - { - _acmLastActivity = chrono::steady_clock::now(); - } return status; } @@ -3605,16 +3487,3 @@ ConnectionI::write(Buffer& buf) } return op; } - -void -ConnectionI::reap() -{ - if (_monitor) - { - _monitor->reap(shared_from_this()); - } - if (_observer) - { - _observer.detach(); - } -} diff --git a/cpp/src/Ice/ConnectionI.h b/cpp/src/Ice/ConnectionI.h index 60309c07f47..6bdd98f2b6e 100644 --- a/cpp/src/Ice/ConnectionI.h +++ b/cpp/src/Ice/ConnectionI.h @@ -5,7 +5,6 @@ #ifndef ICE_CONNECTION_I_H #define ICE_CONNECTION_I_H -#include "ACM.h" #include "ConnectionFactoryF.h" #include "ConnectionOptions.h" #include "ConnectorF.h" @@ -148,8 +147,6 @@ namespace Ice void updateObserver(); - void monitor(const std::chrono::steady_clock::time_point&, const IceInternal::ACMConfig&); - IceInternal::AsyncStatus sendAsyncRequest(const IceInternal::OutgoingAsyncBasePtr&, bool, bool, int); const IceInternal::BatchRequestQueuePtr& getBatchRequestQueue() const; @@ -165,10 +162,6 @@ namespace Ice std::function heartbeatAsync(std::function, std::function = nullptr) final; - void - setACM(const std::optional&, const std::optional&, const std::optional&) final; - ACM getACM() noexcept final; - void asyncRequestCanceled(const IceInternal::OutgoingAsyncBasePtr&, std::exception_ptr) final; IceInternal::EndpointIPtr endpoint() const; @@ -243,21 +236,21 @@ namespace Ice ConnectionI( const Ice::CommunicatorPtr&, const IceInternal::InstancePtr&, - const IceInternal::ACMMonitorPtr&, const IceInternal::TransceiverPtr&, const IceInternal::ConnectorPtr&, const IceInternal::EndpointIPtr&, const std::shared_ptr&, + std::function, const ConnectionOptions&) noexcept; static ConnectionIPtr create( const Ice::CommunicatorPtr&, const IceInternal::InstancePtr&, - const IceInternal::ACMMonitorPtr&, const IceInternal::TransceiverPtr&, const IceInternal::ConnectorPtr&, const IceInternal::EndpointIPtr&, const std::shared_ptr&, + std::function, const ConnectionOptions&); enum State @@ -312,11 +305,8 @@ namespace Ice IceInternal::SocketOperation read(IceInternal::Buffer&); IceInternal::SocketOperation write(IceInternal::Buffer&); - void reap(); - Ice::CommunicatorPtr _communicator; const IceInternal::InstancePtr _instance; - IceInternal::ACMMonitorPtr _monitor; const IceInternal::TransceiverPtr _transceiver; const std::string _desc; const std::string _type; @@ -341,11 +331,12 @@ namespace Ice std::function _connectionStartCompleted; std::function _connectionStartFailed; + // This function must be called outside the ConnectionI lock to avoid lock acquisition deadlocks. + const std::function _removeFromFactory; + const bool _warn; const bool _warnUdp; - std::chrono::steady_clock::time_point _acmLastActivity; - const int _compressionLevel; std::int32_t _nextRequestId; diff --git a/cpp/src/Ice/Instance.cpp b/cpp/src/Ice/Instance.cpp index 72ddf47df81..2d200ae99cb 100644 --- a/cpp/src/Ice/Instance.cpp +++ b/cpp/src/Ice/Instance.cpp @@ -531,20 +531,6 @@ IceInternal::Instance::serverConnectionOptions(const string& adapterName) const return connectionOptions; } -const ACMConfig& -IceInternal::Instance::clientACM() const -{ - // No mutex lock, immutable. - return _clientACM; -} - -const ACMConfig& -IceInternal::Instance::serverACM() const -{ - // No mutex lock, immutable. - return _serverACM; -} - Ice::ObjectPrx IceInternal::Instance::createAdmin(const ObjectAdapterPtr& adminAdapter, const Identity& adminIdentity) { @@ -1120,15 +1106,6 @@ IceInternal::Instance::initialize(const Ice::CommunicatorPtr& communicator) const_cast(_defaultsAndOverrides) = make_shared(_initData.properties, _initData.logger); - const ACMConfig defaultClientACM(_initData.properties, _initData.logger, "Ice.ACM", ACMConfig(false)); - const ACMConfig defaultServerACM(_initData.properties, _initData.logger, "Ice.ACM", ACMConfig(true)); - - const_cast(_clientACM) = - ACMConfig(_initData.properties, _initData.logger, "Ice.ACM.Client", defaultClientACM); - - const_cast(_serverACM) = - ACMConfig(_initData.properties, _initData.logger, "Ice.ACM.Server", defaultServerACM); - { const PropertiesPtr& properties = _initData.properties; ConnectionOptions& connectionOptions = const_cast(_clientConnectionOptions); diff --git a/cpp/src/Ice/Instance.h b/cpp/src/Ice/Instance.h index 7aca4bc1b89..3cdac2a9204 100644 --- a/cpp/src/Ice/Instance.h +++ b/cpp/src/Ice/Instance.h @@ -6,7 +6,6 @@ #define ICE_INSTANCE_H #include "../IceSSL/SSLEngineF.h" -#include "ACM.h" #include "ConnectionFactoryF.h" #include "ConnectionOptions.h" #include "DefaultsAndOverridesF.h" @@ -101,8 +100,6 @@ namespace IceInternal size_t classGraphDepthMax() const { return _classGraphDepthMax; } Ice::ToStringMode toStringMode() const { return _toStringMode; } bool acceptClassCycles() const { return _acceptClassCycles; } - const ACMConfig& clientACM() const; - const ACMConfig& serverACM() const; const Ice::ConnectionOptions& clientConnectionOptions() const noexcept { return _clientConnectionOptions; } Ice::ConnectionOptions serverConnectionOptions(const std::string& adapterName) const; @@ -162,8 +159,6 @@ namespace IceInternal const size_t _classGraphDepthMax; // Immutable, not reset by destroy(). const Ice::ToStringMode _toStringMode; // Immutable, not reset by destroy() const bool _acceptClassCycles; // Immutable, not reset by destroy() - ACMConfig _clientACM; - ACMConfig _serverACM; Ice::ConnectionOptions _clientConnectionOptions; RouterManagerPtr _routerManager; LocatorManagerPtr _locatorManager; diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index f6d7fa8dec5..1c3948ae2f3 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -855,15 +855,6 @@ Ice::ObjectAdapterI::getThreadPool() const } } -IceInternal::ACMConfig -Ice::ObjectAdapterI::getACM() const -{ - // Not check for deactivation here! - - assert(_instance); // Must not be called after destroy(). - return _acm; -} - void Ice::ObjectAdapterI::setAdapterOnConnection(const Ice::ConnectionIPtr& connection) { @@ -902,7 +893,6 @@ Ice::ObjectAdapterI::initialize(optional router) if (_noConfig) { _reference = _instance->referenceFactory()->create("dummy -t", ""); - const_cast(_acm) = _instance->serverACM(); return; } @@ -953,9 +943,6 @@ Ice::ObjectAdapterI::initialize(optional router) "invalid proxy options `" + proxyOptions + "' for object adapter `" + _name + "'"); } - const_cast(_acm) = - ACMConfig(properties, _communicator->getLogger(), _name + ".ACM", _instance->serverACM()); - { const int defaultMessageSizeMax = static_cast(_instance->messageSizeMax() / 1024); int32_t num = properties->getPropertyAsIntWithDefault(_name + ".MessageSizeMax", defaultMessageSizeMax); @@ -1381,10 +1368,6 @@ bool Ice::ObjectAdapterI::filterProperties(StringSeq& unknownProps) { static const string suffixes[] = { - "ACM", - "ACM.Close", - "ACM.Heartbeat", - "ACM.Timeout", "AdapterId", "Connection.CloseTimeout", "Connection.ConnectTimeout", diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h index df89f74e400..2902f02f12a 100644 --- a/cpp/src/Ice/ObjectAdapterI.h +++ b/cpp/src/Ice/ObjectAdapterI.h @@ -5,8 +5,8 @@ #ifndef ICE_OBJECT_ADAPTER_I_H #define ICE_OBJECT_ADAPTER_I_H -#include "ACM.h" #include "ConnectionFactoryF.h" +#include "ConnectionI.h" #include "EndpointIF.h" #include "Ice/BuiltinSequences.h" #include "Ice/CommunicatorF.h" @@ -97,7 +97,6 @@ namespace Ice void decDirectCount(); IceInternal::ThreadPoolPtr getThreadPool() const; - IceInternal::ACMConfig getACM() const; void setAdapterOnConnection(const Ice::ConnectionIPtr&); size_t messageSizeMax() const { return _messageSizeMax; } @@ -142,7 +141,6 @@ namespace Ice CommunicatorPtr _communicator; IceInternal::ObjectAdapterFactoryPtr _objectAdapterFactory; IceInternal::ThreadPoolPtr _threadPool; - IceInternal::ACMConfig _acm; const IceInternal::ServantManagerPtr _servantManager; // There is no need to clear _dispatchPipeline during destroy because _dispatchPipeline does not hold onto this diff --git a/cpp/src/Ice/msbuild/ice/ice.vcxproj b/cpp/src/Ice/msbuild/ice/ice.vcxproj index 544c46957e4..4505bd53279 100644 --- a/cpp/src/Ice/msbuild/ice/ice.vcxproj +++ b/cpp/src/Ice/msbuild/ice/ice.vcxproj @@ -510,7 +510,6 @@ - diff --git a/cpp/src/Ice/msbuild/ice/ice.vcxproj.filters b/cpp/src/Ice/msbuild/ice/ice.vcxproj.filters index f419a8c8e36..729e2302a28 100644 --- a/cpp/src/Ice/msbuild/ice/ice.vcxproj.filters +++ b/cpp/src/Ice/msbuild/ice/ice.vcxproj.filters @@ -243,9 +243,6 @@ Source Files - - Source Files - Source Files diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp index 48b3d5f5f83..148ffa897b3 100644 --- a/cpp/src/IceGrid/Client.cpp +++ b/cpp/src/IceGrid/Client.cpp @@ -299,16 +299,15 @@ run(const Ice::StringSeq& args) int status = 0; try { - int acmTimeout = 0; + [[maybe_unused]] int remoteIdleTimeout = 0; if (!communicator->getDefaultLocator() && !communicator->getDefaultRouter()) { if (!host.empty()) { - const int timeout = 3000; // 3s connection timeout. ostringstream os; os << "Ice/LocatorFinder" << (ssl ? " -s" : ""); - os << ":tcp -h \"" << host << "\" -p " << (port == 0 ? 4061 : port) << " -t " << timeout; - os << ":ssl -h \"" << host << "\" -p " << (port == 0 ? 4062 : port) << " -t " << timeout; + os << ":tcp -h \"" << host << "\" -p " << (port == 0 ? 4061 : port); + os << ":ssl -h \"" << host << "\" -p " << (port == 0 ? 4062 : port); Ice::LocatorFinderPrx finder{communicator, os.str()}; try { @@ -443,7 +442,7 @@ run(const Ice::StringSeq& args) try { - acmTimeout = router->getACMTimeout(); + remoteIdleTimeout = router->getACMTimeout(); } catch (const Ice::OperationNotExistException&) { @@ -592,7 +591,7 @@ run(const Ice::StringSeq& args) try { - acmTimeout = registry->getACMTimeout(); + remoteIdleTimeout = registry->getACMTimeout(); } catch (const Ice::OperationNotExistException&) { @@ -607,10 +606,7 @@ run(const Ice::StringSeq& args) return 1; } - if (acmTimeout > 0) - { - session->ice_getConnection()->setACM(acmTimeout, nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - } + // TODO: fail if the remote idle timeout is not compatible with the local idle timeout. { lock_guard lock(staticMutex); diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp index fa99df32f61..6a1aa99be3c 100644 --- a/cpp/src/IceGrid/IceGridNode.cpp +++ b/cpp/src/IceGrid/IceGridNode.cpp @@ -775,11 +775,6 @@ NodeService::initializeCommunicator(int& argc, char* argv[], const Initializatio // setupThreadPool(initData.properties, "Ice.ThreadPool.Client", 1, 100); - // - // Close idle connections - // - initData.properties->setProperty("Ice.ACM.Close", "3"); - return Service::initializeCommunicator(argc, argv, initData, version); } diff --git a/cpp/src/IceGrid/IceGridRegistry.cpp b/cpp/src/IceGrid/IceGridRegistry.cpp index 1f8f257138b..bf212349aea 100644 --- a/cpp/src/IceGrid/IceGridRegistry.cpp +++ b/cpp/src/IceGrid/IceGridRegistry.cpp @@ -195,11 +195,6 @@ RegistryService::initializeCommunicator( // setupThreadPool(initData.properties, "Ice.ThreadPool.Client", 1, 100); - // - // Close idle connections - // - initData.properties->setProperty("Ice.ACM.Close", "3"); - return Service::initializeCommunicator(argc, argv, initData, version); } diff --git a/cpp/src/IceGrid/InternalRegistryI.cpp b/cpp/src/IceGrid/InternalRegistryI.cpp index 1466409b075..8cabf3a5821 100644 --- a/cpp/src/IceGrid/InternalRegistryI.cpp +++ b/cpp/src/IceGrid/InternalRegistryI.cpp @@ -34,10 +34,11 @@ InternalRegistryI::InternalRegistryI( _session(session) { auto properties = database->getCommunicator()->getProperties(); + // TODO: temporary. For now, synchronized with the default idle timeout. _nodeSessionTimeout = - chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.NodeSessionTimeout", 30)); + chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.NodeSessionTimeout", 60)); _replicaSessionTimeout = - chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.ReplicaSessionTimeout", 30)); + chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.ReplicaSessionTimeout", 60)); _requireNodeCertCN = properties->getPropertyAsIntWithDefault("IceGrid.Registry.RequireNodeCertCN", 0); _requireReplicaCertCN = properties->getPropertyAsIntWithDefault("IceGrid.Registry.RequireReplicaCertCN", 0); } diff --git a/cpp/src/IceGrid/ReapThread.cpp b/cpp/src/IceGrid/ReapThread.cpp index 646c0dfa0a9..05de108ddb4 100644 --- a/cpp/src/IceGrid/ReapThread.cpp +++ b/cpp/src/IceGrid/ReapThread.cpp @@ -61,7 +61,8 @@ ReapThread::run() } else if ((chrono::steady_clock::now() - p->item->timestamp()) > p->timeout) { - reap.push_back(*p); + // TODO: for now, we no longer reap anything. All this code should be removed in a follow-up PR. + // reap.push_back(*p); } else { diff --git a/cpp/src/IceGrid/RegistryI.cpp b/cpp/src/IceGrid/RegistryI.cpp index 8dfc50607a4..373601127f3 100644 --- a/cpp/src/IceGrid/RegistryI.cpp +++ b/cpp/src/IceGrid/RegistryI.cpp @@ -248,7 +248,9 @@ RegistryI::startImpl() _replicaName = properties->getPropertyWithDefault("IceGrid.Registry.ReplicaName", "Master"); _master = _replicaName == "Master"; - _sessionTimeout = chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.SessionTimeout", 30)); + + // TODO: temporary. For now, synchronized with the default idle timeout. + _sessionTimeout = chrono::seconds(properties->getPropertyAsIntWithDefault("IceGrid.Registry.SessionTimeout", 60)); if (!_initFromReplica.empty() && (_initFromReplica == _replicaName || (_master && _initFromReplica == "Master"))) { @@ -257,25 +259,6 @@ RegistryI::startImpl() return false; } - if (_sessionTimeout > 0s && properties->getProperty("IceGrid.Registry.Client.ACM.Timeout").empty()) - { - properties->setProperty("IceGrid.Registry.Client.ACM.Timeout", to_string(secondsToInt(_sessionTimeout))); - } - - if (properties->getProperty("IceGrid.Registry.Server.ACM.Timeout").empty()) - { - properties->setProperty("IceGrid.Registry.Server.ACM.Timeout", "30"); - } - - if (properties->getProperty("IceGrid.Registry.Internal.ACM.Timeout").empty()) - { - int nt = properties->getPropertyAsIntWithDefault("IceGrid.Registry.NodeSessionTimeout", 30); - int rt = properties->getPropertyAsIntWithDefault("IceGrid.Registry.ReplicaSessionTimeout", 30); - properties->setProperty("IceGrid.Registry.Internal.ACM.Timeout", to_string(max(nt, rt))); - } - - properties->setProperty("Ice.ACM.Server.Close", "3"); // Close on invocation and idle. - if (!_master && !_communicator->getDefaultLocator()) { Error out(_communicator->getLogger()); @@ -1104,9 +1087,12 @@ RegistryI::getSessionTimeout(const Ice::Current&) const } int -RegistryI::getACMTimeout(const Ice::Current& current) const +RegistryI::getACMTimeout(const Ice::Current&) const { - return current.con->getACM().timeout; + // TODO: better way to retrieve idle timeout + auto properties = _communicator->getProperties(); + int idleTimeout = properties->getPropertyAsIntWithDefault("Ice.Connection.IdleTimeout", 60); + return properties->getPropertyAsIntWithDefault("IceGrid.Registry.Client.Connection.IdleTimeout", idleTimeout); } string diff --git a/cpp/test/Glacier2/override/test.py b/cpp/test/Glacier2/override/test.py index 5b38833cb41..4342c269045 100644 --- a/cpp/test/Glacier2/override/test.py +++ b/cpp/test/Glacier2/override/test.py @@ -19,7 +19,7 @@ "Glacier2.Filter.Category.Accept": '"c"', "Glacier2.PermissionsVerifier": "Glacier2/NullPermissionsVerifier", "Glacier2.Client.ForwardContext": "1", - "Glacier2.Client.ACM.Timeout": '"30"', + "Glacier2.Client.Connection.IdleTimeout": '"30"', "Glacier2.Client.Trace.Override": "0", "Glacier2.Client.Trace.Request": "0", "Glacier2.Server.Trace.Override": "0", diff --git a/cpp/test/Ice/acm/AllTests.cpp b/cpp/test/Ice/acm/AllTests.cpp deleted file mode 100644 index 969adba7754..00000000000 --- a/cpp/test/Ice/acm/AllTests.cpp +++ /dev/null @@ -1,599 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include "Ice/Ice.h" -#include "Test.h" -#include "TestHelper.h" - -#include -#include -#include - -using namespace std; -using namespace Test; -namespace -{ - string toString(int value) - { - ostringstream os; - os << value; - return os.str(); - } - - class LoggerI final : public Ice::Logger, public enable_shared_from_this - { - public: - LoggerI() : _started(false) {} - - void start() - { - lock_guard lock(_mutex); - _started = true; - dump(); - } - - void print(const string& msg) final - { - lock_guard lock(_mutex); - _messages.push_back(msg); - if (_started) - { - dump(); - } - } - - void trace(const string& category, const string& message) final - { - lock_guard lock(_mutex); - _messages.push_back("[" + category + "] " + message); - if (_started) - { - dump(); - } - } - - void warning(const string& message) final - { - lock_guard lock(_mutex); - _messages.push_back("warning: " + message); - if (_started) - { - dump(); - } - } - - void error(const string& message) final - { - lock_guard lock(_mutex); - _messages.push_back("error: " + message); - if (_started) - { - dump(); - } - } - - string getPrefix() final { return ""; } - - Ice::LoggerPtr cloneWithPrefix(const string&) final { return shared_from_this(); } - - private: - void dump() - { - for (const auto& message : _messages) - { - cout << message << endl; - } - _messages.clear(); - } - - bool _started; - vector _messages; - mutex _mutex; - }; - using LoggerIPtr = shared_ptr; - - class TestCase : public enable_shared_from_this - { - public: - TestCase(const string& name, const RemoteCommunicatorPrx& com) - : _testCaseName(name), - _com(com), - _logger(new LoggerI()), - _clientACMTimeout(-1), - _clientACMClose(-1), - _clientACMHeartbeat(-1), - _serverACMTimeout(-1), - _serverACMClose(-1), - _serverACMHeartbeat(-1), - _heartbeat(0), - _closed(false) - { - } - - void init() - { - _adapter = _com->createObjectAdapter(_serverACMTimeout, _serverACMClose, _serverACMHeartbeat); - - Ice::InitializationData initData; - initData.properties = _com->ice_getCommunicator()->getProperties()->clone(); - initData.logger = _logger; - initData.properties->setProperty("Ice.ACM.Timeout", "2"); - if (_clientACMTimeout >= 0) - { - initData.properties->setProperty("Ice.ACM.Client.Timeout", toString(_clientACMTimeout)); - } - if (_clientACMClose >= 0) - { - initData.properties->setProperty("Ice.ACM.Client.Close", toString(_clientACMClose)); - } - if (_clientACMHeartbeat >= 0) - { - initData.properties->setProperty("Ice.ACM.Client.Heartbeat", toString(_clientACMHeartbeat)); - } - _communicator = Ice::initialize(initData); - } - - void destroy() - { - _adapter->deactivate(); - _communicator->destroy(); - } - - void join(thread& t) - { - cout << "testing " << _testCaseName << "... " << flush; - _logger->start(); - t.join(); - if (_msg.empty()) - { - cout << "ok" << endl; - } - else - { - cout << "failed! " << endl << _msg; - test(false); - } - } - - void run() - { - auto proxy = TestIntfPrx(_communicator, _adapter->getTestIntf()->ice_toString()); - try - { - auto self = shared_from_this(); - proxy->ice_getConnection()->setCloseCallback([self](Ice::ConnectionPtr connection) - { self->closed(std::move(connection)); }); - proxy->ice_getConnection()->setHeartbeatCallback([self](Ice::ConnectionPtr connection) - { self->heartbeat(std::move(connection)); }); - runTestCase(_adapter.value(), proxy); - } - catch (const exception& ex) - { - _msg = string("unexpected exception:\n") + ex.what(); - } - catch (...) - { - _msg = "unknown exception"; - } - } - - void heartbeat(const Ice::ConnectionPtr&) - { - lock_guard lock(_mutex); - ++_heartbeat; - } - - void closed(const Ice::ConnectionPtr&) - { - lock_guard lock(_mutex); - _closed = true; - _conditionVariable.notify_one(); - } - - void waitForClosed() - { - unique_lock lock(_mutex); - if (!_conditionVariable.wait_for(lock, chrono::seconds(30), [this] { return _closed; })) - { - test(false); // Waited for more than 30s for close, something's wrong. - } - } - - virtual void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx&) = 0; - - void setClientACM(int timeout, int close, int heartbeat) - { - _clientACMTimeout = timeout; - _clientACMClose = close; - _clientACMHeartbeat = heartbeat; - } - - void setServerACM(int timeout, int close, int heartbeat) - { - _serverACMTimeout = timeout; - _serverACMClose = close; - _serverACMHeartbeat = heartbeat; - } - - protected: - const string _testCaseName; - const RemoteCommunicatorPrx _com; - string _msg; - LoggerIPtr _logger; - - Ice::CommunicatorPtr _communicator; - optional _adapter; - - int _clientACMTimeout; - int _clientACMClose; - int _clientACMHeartbeat; - int _serverACMTimeout; - int _serverACMClose; - int _serverACMHeartbeat; - - int _heartbeat; - bool _closed; - mutex _mutex; - condition_variable _conditionVariable; - }; - using TestCasePtr = shared_ptr; - - class InvocationHeartbeatTest final : public TestCase - { - public: - InvocationHeartbeatTest(const RemoteCommunicatorPrx& com) : TestCase("invocation heartbeat", com) - { - setServerACM(1, -1, -1); // Faster ACM to make sure we receive enough ACM heartbeats - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - proxy->sleep(4); - - lock_guard lock(_mutex); - test(_heartbeat >= 4); - } - }; - - class InvocationHeartbeatOnHoldTest final : public TestCase - { - public: - InvocationHeartbeatOnHoldTest(const RemoteCommunicatorPrx& com) - : TestCase("invocation with heartbeat on hold", com) - { - // Use default ACM configuration. - } - - void runTestCase(const RemoteObjectAdapterPrx& adapter, const TestIntfPrx& proxy) final - { - try - { - // When the OA is put on hold, connections shouldn't - // send heartbeats, the invocation should therefore - // fail. - proxy->sleepAndHold(10); - test(false); - } - catch (const Ice::ConnectionTimeoutException&) - { - adapter->activate(); - proxy->interruptSleep(); - - waitForClosed(); - } - } - }; - - class InvocationNoHeartbeatTest final : public TestCase - { - public: - InvocationNoHeartbeatTest(const RemoteCommunicatorPrx& com) : TestCase("invocation with no heartbeat", com) - { - setServerACM(2, 2, 0); // Disable heartbeat on invocations - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - try - { - // Heartbeats are disabled on the server, the - // invocation should fail since heartbeats are - // expected. - proxy->sleep(10); - test(false); - } - catch (const Ice::ConnectionTimeoutException&) - { - proxy->interruptSleep(); - - waitForClosed(); - - lock_guard lock(_mutex); - test(_heartbeat == 0); - } - } - }; - - class InvocationHeartbeatCloseOnIdleTest final : public TestCase - { - public: - InvocationHeartbeatCloseOnIdleTest(const RemoteCommunicatorPrx& com) - : TestCase("invocation with no heartbeat and close on idle", com) - { - setClientACM(1, 1, 0); // Only close on idle. - setServerACM(1, 2, 0); // Disable heartbeat on invocations - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - // No close on invocation, the call should succeed this time. - proxy->sleep(3); - - lock_guard lock(_mutex); - test(_heartbeat == 0); - test(!_closed); - } - }; - - class CloseOnIdleTest final : public TestCase - { - public: - CloseOnIdleTest(const RemoteCommunicatorPrx& com) : TestCase("close on idle", com) - { - setClientACM(1, 1, 0); // Only close on idle - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx&) final - { - waitForClosed(); - - lock_guard lock(_mutex); - test(_heartbeat == 0); - } - }; - - class CloseOnInvocationTest final : public TestCase - { - public: - CloseOnInvocationTest(const RemoteCommunicatorPrx& com) : TestCase("close on invocation", com) - { - setClientACM(1, 2, 0); // Only close on invocation - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx&) final - { - this_thread::sleep_for(chrono::milliseconds(3000)); // Idle for 3 seconds - - lock_guard lock(_mutex); - test(_heartbeat == 0); - test(!_closed); - } - }; - - class CloseOnIdleAndInvocationTest final : public TestCase - { - public: - CloseOnIdleAndInvocationTest(const RemoteCommunicatorPrx& com) : TestCase("close on idle and invocation", com) - { - setClientACM(3, 3, 0); // Only close on idle and invocation - } - - void runTestCase(const RemoteObjectAdapterPrx& adapter, const TestIntfPrx&) final - { - // - // Put the adapter on hold. The server will not respond to - // the graceful close. This allows to test whether or not - // the close is graceful or forceful. - // - adapter->hold(); - this_thread::sleep_for(chrono::milliseconds(5000)); // Idle for 5 seconds - - { - lock_guard lock(_mutex); - test(_heartbeat == 0); - test(!_closed); // Not closed yet because of graceful close. - } - - adapter->activate(); - - waitForClosed(); - } - }; - - class ForcefulCloseOnIdleAndInvocationTest final : public TestCase - { - public: - ForcefulCloseOnIdleAndInvocationTest(const RemoteCommunicatorPrx& com) - : TestCase("forceful close on idle and invocation", com) - { - setClientACM(1, 4, 0); // Only close on idle and invocation - } - - void runTestCase(const RemoteObjectAdapterPrx& adapter, const TestIntfPrx&) final - { - adapter->hold(); - - waitForClosed(); - - lock_guard lock(_mutex); - test(_heartbeat == 0); - } - }; - - class HeartbeatOnIdleTest final : public TestCase - { - public: - HeartbeatOnIdleTest(const RemoteCommunicatorPrx& com) : TestCase("heartbeat on idle", com) - { - setServerACM(1, -1, 2); // Enable server heartbeats. - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx&) final - { - this_thread::sleep_for(chrono::milliseconds(3000)); - - lock_guard lock(_mutex); - test(_heartbeat >= 3); - } - }; - - class HeartbeatAlwaysTest final : public TestCase - { - public: - HeartbeatAlwaysTest(const RemoteCommunicatorPrx& com) : TestCase("heartbeat always", com) - { - setServerACM(1, -1, 3); // Enable server heartbeats. - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - for (int i = 0; i < 10; ++i) - { - proxy->ice_ping(); - this_thread::sleep_for(chrono::milliseconds(300)); - } - - lock_guard lock(_mutex); - test(_heartbeat >= 3); - } - }; - - class HeartbeatManualTest final : public TestCase - { - public: - HeartbeatManualTest(const RemoteCommunicatorPrx& com) : TestCase("manual heartbeats", com) - { - // - // Disable heartbeats. - // - setClientACM(10, -1, 0); - setServerACM(10, -1, 0); - } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - proxy->startHeartbeatCount(); - Ice::ConnectionPtr con = proxy->ice_getConnection(); - con->heartbeat(); - con->heartbeat(); - con->heartbeat(); - con->heartbeat(); - con->heartbeat(); - proxy->waitForHeartbeatCount(5); - } - }; - - class SetACMTest final : public TestCase - { - public: - SetACMTest(const RemoteCommunicatorPrx& com) : TestCase("setACM/getACM", com) { setClientACM(15, 4, 0); } - - void runTestCase(const RemoteObjectAdapterPrx&, const TestIntfPrx& proxy) final - { - Ice::ConnectionPtr con = proxy->ice_getConnection(); - - try - { - con->setACM(-19, nullopt, nullopt); - test(false); - } - catch (const invalid_argument&) - { - } - - Ice::ACM acm; - acm = con->getACM(); - test(acm.timeout == 15); - test(acm.close == Ice::ACMClose::CloseOnIdleForceful); - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatOff); - - con->setACM(nullopt, nullopt, nullopt); - acm = con->getACM(); - test(acm.timeout == 15); - test(acm.close == Ice::ACMClose::CloseOnIdleForceful); - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatOff); - - con->setACM(1, Ice::ACMClose::CloseOnInvocationAndIdle, Ice::ACMHeartbeat::HeartbeatAlways); - acm = con->getACM(); - test(acm.timeout == 1); - test(acm.close == Ice::ACMClose::CloseOnInvocationAndIdle); - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatAlways); - - // Make sure the client sends a few heartbeats to the server. - proxy->startHeartbeatCount(); - proxy->waitForHeartbeatCount(2); - - auto p1 = promise(); - con->setCloseCallback([&p1](shared_ptr) { p1.set_value(); }); - - con->close(Ice::ConnectionClose::Gracefully); - p1.get_future().wait(); - - try - { - con->throwException(); - test(false); - } - catch (const Ice::ConnectionManuallyClosedException&) - { - } - - auto p2 = promise(); - con->setCloseCallback([&p2](shared_ptr) { p2.set_value(); }); - p2.get_future().wait(); - - con->setHeartbeatCallback([](shared_ptr) {}); - } - }; -} - -void -allTests(Test::TestHelper* helper) -{ - Ice::CommunicatorPtr communicator = helper->communicator(); - RemoteCommunicatorPrx com(communicator, "communicator:" + helper->getTestEndpoint()); - - vector tests; - - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - tests.push_back(make_shared(com)); - - for (const auto& testCase : tests) - { - testCase->init(); - } - - vector> threads; - for (const auto& testCase : tests) - { - thread thread([testCase]() { testCase->run(); }); - threads.push_back(make_pair(std::move(thread), testCase)); - } - - for (auto& [thread, testCase] : threads) - { - testCase->join(thread); - } - - for (const auto& testCase : tests) - { - testCase->destroy(); - } - - cout << "shutting down... " << flush; - com->shutdown(); - cout << "ok" << endl; -} diff --git a/cpp/test/Ice/acm/Client.cpp b/cpp/test/Ice/acm/Client.cpp deleted file mode 100644 index 00c34085697..00000000000 --- a/cpp/test/Ice/acm/Client.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. - -#include "Ice/Ice.h" -#include "Test.h" -#include "TestHelper.h" - -using namespace std; - -class Client : public Test::TestHelper -{ -public: - void run(int, char**); -}; - -void -Client::run(int argc, char** argv) -{ - Ice::PropertiesPtr properties = createTestProperties(argc, argv); - properties->setProperty("Ice.Warn.Connections", "0"); - Ice::CommunicatorHolder communicator = initialize(argc, argv, properties); - void allTests(Test::TestHelper*); - allTests(this); -} - -DEFINE_TEST(Client) diff --git a/cpp/test/Ice/acm/Server.cpp b/cpp/test/Ice/acm/Server.cpp deleted file mode 100644 index 41000bfed2d..00000000000 --- a/cpp/test/Ice/acm/Server.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include "Ice/Ice.h" -#include "TestHelper.h" -#include "TestI.h" - -using namespace std; - -class Server : public Test::TestHelper -{ -public: - void run(int, char**); -}; - -void -Server::run(int argc, char** argv) -{ - Ice::PropertiesPtr properties = createTestProperties(argc, argv); - properties->setProperty("Ice.Warn.Connections", "0"); - properties->setProperty("Ice.ACM.Timeout", "1"); - Ice::CommunicatorHolder communicator = initialize(argc, argv, properties); - communicator->getProperties()->setProperty("TestAdapter.Endpoints", getTestEndpoint()); - communicator->getProperties()->setProperty("TestAdapter.ACM.Timeout", "0"); - Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("TestAdapter"); - Ice::Identity id = Ice::stringToIdentity("communicator"); - adapter->add(std::make_shared(), id); - adapter->activate(); - - serverReady(); - - // Disable ready print for further adapters. - communicator->getProperties()->setProperty("Ice.PrintAdapterReady", "0"); - - communicator->waitForShutdown(); -} - -DEFINE_TEST(Server) diff --git a/cpp/test/Ice/acm/Test.ice b/cpp/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/cpp/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/cpp/test/Ice/acm/TestI.cpp b/cpp/test/Ice/acm/TestI.cpp deleted file mode 100644 index f0218ecb03c..00000000000 --- a/cpp/test/Ice/acm/TestI.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#include "TestI.h" -#include "Ice/Ice.h" - -using namespace std; -using namespace Ice; -using namespace Test; - -namespace -{ - string toString(int value) - { - ostringstream os; - os << value; - return os.str(); - } -} - -optional -RemoteCommunicatorI::createObjectAdapter(int timeout, int close, int heartbeat, const Current& current) -{ - Ice::CommunicatorPtr com = current.adapter->getCommunicator(); - Ice::PropertiesPtr properties = com->getProperties(); - string protocol = properties->getPropertyWithDefault("Ice.Default.Protocol", "tcp"); - string opts; - if (protocol != "bt") - { - opts = " -h \"" + properties->getPropertyWithDefault("Ice.Default.Host", "127.0.0.1") + "\""; - } - - string name = generateUUID(); - if (timeout >= 0) - { - properties->setProperty(name + ".ACM.Timeout", toString(timeout)); - } - if (close >= 0) - { - properties->setProperty(name + ".ACM.Close", toString(close)); - } - if (heartbeat >= 0) - { - properties->setProperty(name + ".ACM.Heartbeat", toString(heartbeat)); - } - properties->setProperty(name + ".ThreadPool.Size", "2"); - ObjectAdapterPtr adapter = com->createObjectAdapterWithEndpoints(name, protocol + opts); - - return RemoteObjectAdapterPrx(current.adapter->addWithUUID(make_shared(adapter))); -} - -void -RemoteCommunicatorI::shutdown(const Ice::Current& current) -{ - current.adapter->getCommunicator()->shutdown(); -} - -RemoteObjectAdapterI::RemoteObjectAdapterI(const Ice::ObjectAdapterPtr& adapter) - : _adapter(adapter), - _testIntf(TestIntfPrx(_adapter->add(make_shared(), stringToIdentity("test")))) -{ - _adapter->activate(); -} - -optional -RemoteObjectAdapterI::getTestIntf(const Ice::Current&) -{ - return _testIntf; -} - -void -RemoteObjectAdapterI::activate(const Ice::Current&) -{ - _adapter->activate(); -} - -void -RemoteObjectAdapterI::hold(const Ice::Current&) -{ - _adapter->hold(); -} - -void -RemoteObjectAdapterI::deactivate(const Ice::Current&) -{ - try - { - _adapter->destroy(); - } - catch (const ObjectAdapterDeactivatedException&) - { - } -} - -void -TestI::sleep(int delay, const Ice::Current&) -{ - unique_lock lock(_mutex); - _condition.wait_for(lock, chrono::seconds(delay)); -} - -void -TestI::sleepAndHold(int delay, const Ice::Current& current) -{ - unique_lock lock(_mutex); - current.adapter->hold(); - _condition.wait_for(lock, chrono::seconds(delay)); -} - -void -TestI::interruptSleep(const Ice::Current&) -{ - lock_guard lock(_mutex); - _condition.notify_all(); -} - -void -TestI::startHeartbeatCount(const Ice::Current& current) -{ - _callback = make_shared(); - HeartbeatCallbackIPtr callback = _callback; - current.con->setHeartbeatCallback([callback](Ice::ConnectionPtr connection) - { callback->heartbeat(std::move(connection)); }); -} - -void -TestI::waitForHeartbeatCount(int count, const Ice::Current&) -{ - assert(_callback); - _callback->waitForCount(count); -} diff --git a/cpp/test/Ice/acm/TestI.h b/cpp/test/Ice/acm/TestI.h deleted file mode 100644 index 9c6651affee..00000000000 --- a/cpp/test/Ice/acm/TestI.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#ifndef TEST_I_H -#define TEST_I_H - -#include "Test.h" -#include -#include - -class RemoteCommunicatorI final : public Test::RemoteCommunicator -{ -public: - std::optional createObjectAdapter(int, int, int, const Ice::Current&) final; - void shutdown(const Ice::Current&) final; -}; - -class RemoteObjectAdapterI final : public Test::RemoteObjectAdapter -{ -public: - RemoteObjectAdapterI(const Ice::ObjectAdapterPtr&); - - std::optional getTestIntf(const Ice::Current&) final; - void activate(const Ice::Current&) final; - void hold(const Ice::Current&) final; - void deactivate(const Ice::Current&) final; - -private: - const Ice::ObjectAdapterPtr _adapter; - const std::optional _testIntf; -}; - -class TestI final : public Test::TestIntf -{ -public: - void sleep(int, const Ice::Current&) final; - void sleepAndHold(int, const Ice::Current&) final; - void interruptSleep(const Ice::Current&) final; - void startHeartbeatCount(const Ice::Current&) final; - void waitForHeartbeatCount(int, const Ice::Current&) final; - -private: - class HeartbeatCallbackI final : public std::enable_shared_from_this - { - public: - HeartbeatCallbackI() : _count(0) {} - - void waitForCount(int count) - { - std::unique_lock lock(_mutex); - _condition.wait(lock, [this, count] { return _count >= count; }); - } - - void heartbeat(const Ice::ConnectionPtr&) - { - std::lock_guard lock(_mutex); - ++_count; - _condition.notify_all(); - } - - private: - int _count; - std::mutex _mutex; - std::condition_variable _condition; - }; - using HeartbeatCallbackIPtr = std::shared_ptr; - - HeartbeatCallbackIPtr _callback; - std::mutex _mutex; - std::condition_variable _condition; -}; - -#endif diff --git a/cpp/test/Ice/acm/msbuild/client/client.vcxproj b/cpp/test/Ice/acm/msbuild/client/client.vcxproj deleted file mode 100644 index bdc8ec2941a..00000000000 --- a/cpp/test/Ice/acm/msbuild/client/client.vcxproj +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {CD25A05C-228D-473F-A86F-6C2DD22085B4} - - - - - - Application - true - $(DefaultPlatformToolset) - - - Application - false - $(DefaultPlatformToolset) - - - Application - true - $(DefaultPlatformToolset) - - - Application - false - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - - - - - - - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/cpp/test/Ice/acm/msbuild/client/client.vcxproj.filters b/cpp/test/Ice/acm/msbuild/client/client.vcxproj.filters deleted file mode 100644 index 42577cba2ae..00000000000 --- a/cpp/test/Ice/acm/msbuild/client/client.vcxproj.filters +++ /dev/null @@ -1,93 +0,0 @@ - - - - - {350e71ec-0634-4362-9640-0ddb51693ac1} - ice - - - {97066ac8-f85a-4275-a8c5-9545a12c72d4} - - - {d2317899-1164-49fe-ac34-f2cf323f882d} - - - {79f1a930-eba9-4433-b456-23b043e25686} - - - {dfc4773c-1b39-4930-b227-2c0020552355} - - - {339228a0-d9f1-4c19-8480-93220e85cfee} - - - {fb3a3c45-d72d-4380-9eff-0eb4618e3a8b} - - - {7817f391-37c8-4123-a22a-a5536361888d} - - - {c8ee4ffc-9788-4bc7-aa07-b68d906b8189} - - - {f85a733a-6846-4ec0-9c74-ec7419b5e614} - - - {b3391a59-e7e9-41c1-a9e0-e590907fa4c5} - - - {0db3a4da-7cde-452e-8565-21f3bcbb1288} - - - {9b928c10-e46c-41b2-982d-6f2e014e7238} - - - {c2624498-4542-4aa0-8922-28785947647d} - - - {75b0e61d-c5fd-421b-b12d-42f921853a9a} - - - - - Source Files - - - Source Files - - - Source Files\x64\Debug - - - Source Files\Win32\Debug - - - Source Files\x64\Release - - - Source Files\Win32\Release - - - - - Header Files\x64\Debug - - - Header Files\Win32\Debug - - - Header Files\x64\Release - - - Header Files\Win32\Release - - - - - - - - Slice Files - - - \ No newline at end of file diff --git a/cpp/test/Ice/acm/msbuild/client/packages.config b/cpp/test/Ice/acm/msbuild/client/packages.config deleted file mode 100644 index a36cb289a52..00000000000 --- a/cpp/test/Ice/acm/msbuild/client/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/cpp/test/Ice/acm/msbuild/server/packages.config b/cpp/test/Ice/acm/msbuild/server/packages.config deleted file mode 100644 index a36cb289a52..00000000000 --- a/cpp/test/Ice/acm/msbuild/server/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/cpp/test/Ice/acm/msbuild/server/server.vcxproj b/cpp/test/Ice/acm/msbuild/server/server.vcxproj deleted file mode 100644 index c929dd27cd6..00000000000 --- a/cpp/test/Ice/acm/msbuild/server/server.vcxproj +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {FC4AC0A5-84D5-461F-BE52-EA686F52773E} - - - - - - Application - true - $(DefaultPlatformToolset) - - - Application - false - $(DefaultPlatformToolset) - - - Application - true - $(DefaultPlatformToolset) - - - Application - false - $(DefaultPlatformToolset) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - true - true - true - ..\..\Test.ice - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/cpp/test/Ice/acm/msbuild/server/server.vcxproj.filters b/cpp/test/Ice/acm/msbuild/server/server.vcxproj.filters deleted file mode 100644 index 865f3a8c598..00000000000 --- a/cpp/test/Ice/acm/msbuild/server/server.vcxproj.filters +++ /dev/null @@ -1,96 +0,0 @@ - - - - - Source Files - - - Source Files - - - Source Files\x64\Debug - - - Source Files\Win32\Debug - - - Source Files\x64\Release - - - Source Files\Win32\Release - - - - - {3cb7c703-ebae-4504-a87b-a6c3486f26c9} - - - {cf727fa0-b4cd-43ad-88f1-8c18029843b8} - ice - - - {fb05cbbe-42ed-413a-bedc-c06ef0f5c4df} - - - {8f93f1cc-29b8-4532-b366-014416068b16} - - - {579631a6-1b9d-4176-93e5-128195951279} - - - {1f3aa8cc-e0a1-43b7-a9e8-91b66cde3489} - - - {9647e436-c1bf-4d03-8ea2-81dda793bebc} - - - {66b4caaa-2068-4f37-8d9f-65e204b9bc79} - - - {a7277aae-0c55-4337-8182-80cfebe633b3} - - - {0a1f7d36-ab97-4d67-86b1-aa0448e98920} - - - {e5ccb4a5-d749-4e6d-9025-15b24797d411} - - - {6fa83d64-b528-4cab-b104-93b10a143040} - - - {71bc3769-d144-4216-9198-7fb8b6125251} - - - {2d4c5d47-0786-4ac3-9f14-7513064d1e2b} - - - {85414859-a745-4f20-9e92-07c043bc4b8d} - - - - - Header Files - - - Header Files\x64\Debug - - - Header Files\Win32\Debug - - - Header Files\x64\Release - - - Header Files\Win32\Release - - - - - - - - Slice Files - - - \ No newline at end of file diff --git a/cpp/test/IceBridge/simple/AllTests.cpp b/cpp/test/IceBridge/simple/AllTests.cpp index 23724861a64..37d27758215 100644 --- a/cpp/test/IceBridge/simple/AllTests.cpp +++ b/cpp/test/IceBridge/simple/AllTests.cpp @@ -196,26 +196,7 @@ allTests(Test::TestHelper* helper) } cout << "ok" << endl; - cout << "testing heartbeats... " << flush; - { - test(cl->getHeartbeatCount() == 0); // No heartbeats enabled by default - - auto p = cl->ice_connectionId("heartbeat"); - p->ice_getConnection()->setACM(1, nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - - auto p2 = cl->ice_connectionId("heartbeat2"); - atomic_int counter = 0; - p2->ice_getConnection()->setHeartbeatCallback([&counter](const auto&) { counter++; }); - p2->enableHeartbeats(); - - int nRetry = 20; - while ((p->getHeartbeatCount() < 1 || counter.load() < 1) && --nRetry > 0) - { - this_thread::sleep_for(500ms); // TODO: check sleep time - } - test(p->getHeartbeatCount() > 0 && counter.load() > 0); - } - cout << "ok" << endl; + // TODO: add heartbeat test cout << "testing server shutdown... " << flush; cl->shutdown(); diff --git a/cpp/test/IceBridge/simple/Test.ice b/cpp/test/IceBridge/simple/Test.ice index 182c470a795..237398f9a2a 100644 --- a/cpp/test/IceBridge/simple/Test.ice +++ b/cpp/test/IceBridge/simple/Test.ice @@ -35,7 +35,6 @@ interface MyClass ["amd"] int getCallbackDatagramCount(); int getHeartbeatCount(); - void enableHeartbeats(); void shutdown(); } diff --git a/cpp/test/IceBridge/simple/TestI.cpp b/cpp/test/IceBridge/simple/TestI.cpp index d8019d51d3d..aee82db01ee 100644 --- a/cpp/test/IceBridge/simple/TestI.cpp +++ b/cpp/test/IceBridge/simple/TestI.cpp @@ -139,13 +139,6 @@ MyClassI::getHeartbeatCount(const Ice::Current& current) return _connections[current.con]; } -void -MyClassI::enableHeartbeats(const Ice::Current& current) -{ - checkConnection(current.con); - current.con->setACM(1, nullopt, Ice::ACMHeartbeat::HeartbeatAlways); -} - void MyClassI::shutdown(const Ice::Current& current) { diff --git a/cpp/test/IceBridge/simple/TestI.h b/cpp/test/IceBridge/simple/TestI.h index 32ece5ebc34..437497a830f 100644 --- a/cpp/test/IceBridge/simple/TestI.h +++ b/cpp/test/IceBridge/simple/TestI.h @@ -36,7 +36,6 @@ class MyClassI final : public Test::MyClass, public std::enable_shared_from_this const Ice::Current&) override; int getHeartbeatCount(const Ice::Current&) override; - void enableHeartbeats(const Ice::Current&) override; void shutdown(const Ice::Current&) override; diff --git a/cpp/test/IceGrid/activation/AllTests.cpp b/cpp/test/IceGrid/activation/AllTests.cpp index dae368f67a5..5fde1dc5cba 100644 --- a/cpp/test/IceGrid/activation/AllTests.cpp +++ b/cpp/test/IceGrid/activation/AllTests.cpp @@ -96,8 +96,6 @@ allTests(Test::TestHelper* helper) optional adminSession = registry->createAdminSession("foo", "bar"); - adminSession->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - optional admin = adminSession->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/admin/test.py b/cpp/test/IceGrid/admin/test.py index b98207ea3b2..86331ef6714 100644 --- a/cpp/test/IceGrid/admin/test.py +++ b/cpp/test/IceGrid/admin/test.py @@ -169,7 +169,6 @@ def expect(admin, msg): def routerProps(process, current): return { - "Glacier2.SessionTimeout": 5, "Glacier2.SessionManager": "TestIceGrid/AdminSessionManager", "Glacier2.PermissionsVerifier": "Glacier2/NullPermissionsVerifier", "Glacier2.SSLSessionManager": "TestIceGrid/AdminSSLSessionManager", diff --git a/cpp/test/IceGrid/allocation/AllTests.cpp b/cpp/test/IceGrid/allocation/AllTests.cpp index 97abb575ac3..ea8d14aeb8b 100644 --- a/cpp/test/IceGrid/allocation/AllTests.cpp +++ b/cpp/test/IceGrid/allocation/AllTests.cpp @@ -259,7 +259,6 @@ allTests(Test::TestHelper* helper) auto registry = RegistryPrx(communicator, communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"); auto session = registry->createAdminSession("foo", "bar"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); auto admin = session->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/deployer/AllTests.cpp b/cpp/test/IceGrid/deployer/AllTests.cpp index ec7f6829869..acdbae6f191 100644 --- a/cpp/test/IceGrid/deployer/AllTests.cpp +++ b/cpp/test/IceGrid/deployer/AllTests.cpp @@ -360,8 +360,6 @@ allTests(Test::TestHelper* helper) optional session = registry->createAdminSession("foo", "bar"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - optional admin = session->getAdmin(); test(admin); @@ -723,8 +721,6 @@ allTestsWithTarget(Test::TestHelper* helper) RegistryPrx registry(comm, comm->getDefaultLocator()->ice_getIdentity().category + "/Registry"); optional session = registry->createAdminSession("foo", "bar"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - optional admin = session->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/noRestartUpdate/AllTests.cpp b/cpp/test/IceGrid/noRestartUpdate/AllTests.cpp index 113046bf244..b03960a45d8 100644 --- a/cpp/test/IceGrid/noRestartUpdate/AllTests.cpp +++ b/cpp/test/IceGrid/noRestartUpdate/AllTests.cpp @@ -145,8 +145,6 @@ allTests(Test::TestHelper* helper) auto session = registry->createAdminSession("foo", "bar"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - auto admin = session->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/replicaGroup/AllTests.cpp b/cpp/test/IceGrid/replicaGroup/AllTests.cpp index 4614cc46a04..1344e5e96e9 100644 --- a/cpp/test/IceGrid/replicaGroup/AllTests.cpp +++ b/cpp/test/IceGrid/replicaGroup/AllTests.cpp @@ -115,8 +115,6 @@ allTests(Test::TestHelper* helper) IceGrid::QueryPrx query(comm, comm->getDefaultLocator()->ice_getIdentity().category + "/Query"); auto session = registry->createAdminSession("foo", "bar"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - auto admin = session->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/replication/AllTests.cpp b/cpp/test/IceGrid/replication/AllTests.cpp index 5681fc3a920..e6834b638d2 100644 --- a/cpp/test/IceGrid/replication/AllTests.cpp +++ b/cpp/test/IceGrid/replication/AllTests.cpp @@ -241,9 +241,6 @@ allTests(Test::TestHelper* helper) communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"); auto adminSession = registry->createAdminSession("foo", "bar"); - - adminSession->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - auto admin = adminSession->getAdmin(); test(admin); diff --git a/cpp/test/IceGrid/replication/test.py b/cpp/test/IceGrid/replication/test.py index 098856ceb28..aa021de0edb 100644 --- a/cpp/test/IceGrid/replication/test.py +++ b/cpp/test/IceGrid/replication/test.py @@ -18,7 +18,6 @@ def clientProps(process, current): "Ice.Trace.Network": 2, "Ice.Trace.Retry": 1, "Ice.Trace.Protocol": 1, - "Ice.ACM.Client.Heartbeat": 2, } if isinstance(platform, Windows) or os.getuid() != 0: diff --git a/cpp/test/IceGrid/session/AllTests.cpp b/cpp/test/IceGrid/session/AllTests.cpp index 6acaaee478e..fd43f762896 100644 --- a/cpp/test/IceGrid/session/AllTests.cpp +++ b/cpp/test/IceGrid/session/AllTests.cpp @@ -416,8 +416,6 @@ allTests(TestHelper* helper) RegistryPrx registry(communicator, communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"); auto session = registry->createAdminSession("admin3", "test3"); - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - auto admin = session->getAdmin(); test(admin); @@ -1045,9 +1043,6 @@ allTests(TestHelper* helper) auto session1 = registry->createAdminSession("admin1", "test1"); auto session2 = registry->createAdminSession("admin2", "test2"); - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - session2->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto admin1 = session1->getAdmin(); auto admin2 = session2->getAdmin(); @@ -1297,9 +1292,6 @@ allTests(TestHelper* helper) cout << "testing application observer... " << flush; auto session1 = registry->createAdminSession("admin1", "test1"); auto admin1 = session1->getAdmin(); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapter(""); auto appObs1 = make_shared("appObs1.2"); auto app1 = adpt1->addWithUUID(appObs1); @@ -1394,9 +1386,6 @@ allTests(TestHelper* helper) optional session1(registry->createAdminSession("admin1", "test1")); auto admin1 = session1->getAdmin(); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapter(""); auto adptObs1 = make_shared("adptObs1"); auto adapter1 = adpt1->addWithUUID(adptObs1); @@ -1479,9 +1468,6 @@ allTests(TestHelper* helper) optional session1(registry->createAdminSession("admin1", "test1")); auto admin1 = session1->getAdmin(); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapter(""); auto objectObs1 = make_shared("objectObs1"); auto object1 = adpt1->addWithUUID(objectObs1); @@ -1532,9 +1518,6 @@ allTests(TestHelper* helper) { cout << "testing node observer... " << flush; auto session1 = registry->createAdminSession("admin1", "test1"); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapter(""); auto appObs1 = make_shared("appObs1.3"); auto app1 = adpt1->addWithUUID(appObs1); @@ -1682,9 +1665,6 @@ allTests(TestHelper* helper) { cout << "testing registry observer... " << flush; auto session1 = registry->createAdminSession("admin1", "test1"); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapter(""); auto appObs1 = make_shared("appObs1.4"); auto app1 = adpt1->addWithUUID(appObs1); @@ -1724,9 +1704,6 @@ allTests(TestHelper* helper) { cout << "testing observer with direct proxy... " << flush; auto session1 = registry->createAdminSession("admin1", "test1"); - - session1->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatOnIdle); - auto adpt1 = communicator->createObjectAdapterWithEndpoints("", "tcp"); auto nodeObs1 = make_shared("nodeObs1"); NodeObserverPrx no1(adpt1->addWithUUID(nodeObs1)); diff --git a/cpp/test/IceGrid/simple/AllTests.cpp b/cpp/test/IceGrid/simple/AllTests.cpp index 91be5543b81..1cb7eeb6c0e 100644 --- a/cpp/test/IceGrid/simple/AllTests.cpp +++ b/cpp/test/IceGrid/simple/AllTests.cpp @@ -283,9 +283,6 @@ allTestsWithDeploy(Test::TestHelper* helper) communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"); optional session = registry->createAdminSession("foo", "bar"); - - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - optional admin = session->getAdmin(); admin->enableServer("server", false); admin->stopServer("server"); diff --git a/cpp/test/IceGrid/update/AllTests.cpp b/cpp/test/IceGrid/update/AllTests.cpp index bf9b66a8eef..6767b7c7834 100644 --- a/cpp/test/IceGrid/update/AllTests.cpp +++ b/cpp/test/IceGrid/update/AllTests.cpp @@ -69,9 +69,6 @@ allTests(Test::TestHelper* helper) communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"); optional session = registry->createAdminSession("foo", "bar"); - - session->ice_getConnection()->setACM(registry->getACMTimeout(), nullopt, Ice::ACMHeartbeat::HeartbeatAlways); - optional admin = session->getAdmin(); test(admin); diff --git a/js/bin/HttpServer.js b/js/bin/HttpServer.js index 492e8cf6c97..9d48af39cc9 100644 --- a/js/bin/HttpServer.js +++ b/js/bin/HttpServer.js @@ -102,7 +102,7 @@ function Init() { res.writeHead(302, { - "Location": "/test/Ice/acm/controller.html&port=15002" + "Location": "/test/Ice/adapterDeactivation/controller.html&port=15002" }); res.end(); } @@ -160,11 +160,11 @@ function Init() { res.writeHead(302, { - "Location": "/test/Ice/acm/index.html" + "Location": "/test/Ice/adapterDeactivation/index.html" }); res.end(); console.log("HTTP/302 (Found) " + req.method + " " + req.url.pathname + " -> " + - "/test/Ice/acm/index.html"); + "/test/Ice/adapterDeactivation/index.html"); } else if((ext == "js" || ext == "css" || ext == "map") && req.headers["accept-encoding"].indexOf("gzip") !== -1) { diff --git a/js/gulpfile.js b/js/gulpfile.js index 496bad5e4bb..6241a8f4616 100644 --- a/js/gulpfile.js +++ b/js/gulpfile.js @@ -247,7 +247,6 @@ else } const tests = [ - "test/Ice/acm", "test/Ice/adapterDeactivation", "test/Ice/ami", "test/Ice/binding", @@ -375,7 +374,6 @@ gulp.task( // TypeScript tests // const tstests = [ - "test/typescript/Ice/acm", "test/typescript/Ice/adapterDeactivation", "test/typescript/Ice/ami", "test/typescript/Ice/binding", diff --git a/js/test/Common/TestSuites.json b/js/test/Common/TestSuites.json index cc006b8c164..1c1301f5eb7 100644 --- a/js/test/Common/TestSuites.json +++ b/js/test/Common/TestSuites.json @@ -1,8 +1,4 @@ { - "Ice/acm": - { - "files": ["Test.js", "Client.js"] - }, "Ice/adapterDeactivation": { "files": ["Test.js", "Client.js"] diff --git a/js/test/Ice/acm/.gitignore b/js/test/Ice/acm/.gitignore deleted file mode 100644 index d158d9308ba..00000000000 --- a/js/test/Ice/acm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Test.js -index.html diff --git a/js/test/Ice/acm/Client.js b/js/test/Ice/acm/Client.js deleted file mode 100644 index 0196e76d63a..00000000000 --- a/js/test/Ice/acm/Client.js +++ /dev/null @@ -1,526 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -(function(module, require, exports) -{ - const Ice = require("ice").Ice; - const TestHelper = require("TestHelper").TestHelper; - const Test = require("Test").Test; - const test = TestHelper.test; - - class LoggerI - { - constructor(out) - { - this._messages = []; - this._out = out; - } - - print(msg) - { - this._messages.push(msg); - } - - trace(category, message) - { - this._messages.push("[" + category + "] " + message); - } - - warning(message) - { - this._messages.push("warning: " + message); - } - - error(message) - { - this._messages.push("error: " + message); - } - - cloneWithPrefix(prefix) - { - return this; - } - - dump() - { - this._messages.forEach(message => this._out.writeLine(message)); - this._messages = []; - } - } - - class TestCase - { - constructor(name, com, out) - { - this._name = name; - this._com = com; - this._logger = new LoggerI(out); - this._msg = null; - - this._clientACMTimeout = -1; - this._clientACMClose = -1; - this._clientACMHeartbeat = -1; - - this._serverACMTimeout = -1; - this._serverACMClose = -1; - this._serverACMHeartbeat = -1; - - this._heartbeat = 0; - this._closed = false; - } - - async init() - { - const initData = new Ice.InitializationData(); - initData.properties = this._com.ice_getCommunicator().getProperties().clone(); - initData.logger = this._logger; - initData.properties.setProperty("Ice.ACM.Timeout", "2"); - if(this._clientACMTimeout >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Timeout", String(this._clientACMTimeout)); - } - if(this._clientACMClose >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Close", String(this._clientACMClose)); - } - if(this._clientACMHeartbeat >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Heartbeat", String(this._clientACMHeartbeat)); - } - this._communicator = Ice.initialize(initData); - - this._adapter = await this._com.createObjectAdapter(this._serverACMTimeout, - this._serverACMClose, - this._serverACMHeartbeat); - } - - async destroy() - { - await this._adapter.deactivate(); - await this._communicator.destroy(); - } - - join(out) - { - this._logger.dump(); - out.write("testing " + this._name + "... "); - if(this._msg === null) - { - out.writeLine("ok"); - } - else - { - out.writeLine("failed! " + this._msg); - test(false); - } - } - - async start() - { - try - { - let prx = await this._adapter.getTestIntf(); - prx = Test.TestIntfPrx.uncheckedCast(this._communicator.stringToProxy(prx.toString())); - const con = await prx.ice_getConnection(); - con.setCloseCallback(connection => - { - this._closed = true; - }); - con.setHeartbeatCallback(connection => ++this._heartbeat); - await this.runTestCase(this._adapter, prx); - } - catch(ex) - { - this._msg = "unexpected exception:\n" + ex.toString() + "\n" + ex.stack; - } - } - - async waitForClosed() - { - const now = Date.now(); - while(!this._closed) - { - await Ice.Promise.delay(100); - if(Date.now() - now >= 2000) - { - test(false); // Waited for more than 2s for close, something's wrong. - } - } - } - - runTestCase(adapter, proxy) - { - test(false); // Abstract - } - - setClientACM(timeout, close, heartbeat) - { - this._clientACMTimeout = timeout; - this._clientACMClose = close; - this._clientACMHeartbeat = heartbeat; - } - - setServerACM(timeout, close, heartbeat) - { - this._serverACMTimeout = timeout; - this._serverACMClose = close; - this._serverACMHeartbeat = heartbeat; - } - } - - class InvocationHeartbeatTest extends TestCase - { - constructor(com, out) - { - super("invocation heartbeat", com, out); - this.setServerACM(1, -1, -1); // Faster ACM to make sure we receive enough ACM heartbeats - } - - async runTestCase(adapter, proxy) - { - await proxy.sleep(4); - test(this._heartbeat >= 4); - } - } - - class InvocationHeartbeatOnHoldTest extends TestCase - { - constructor(com, out) - { - super("invocation with heartbeat on hold", com, out); - // Use default ACM configuration. - } - - async runTestCase(adapter, proxy) - { - // When the OA is put on hold, connections shouldn't - // send heartbeats, the invocation should therefore - // fail. - try - { - await proxy.sleepAndHold(10); - test(false); - } - catch(ex) - { - await adapter.activate(); - await proxy.interruptSleep(); - await this.waitForClosed(); - } - } - } - - class InvocationNoHeartbeatTest extends TestCase - { - constructor(com, out) - { - super("invocation with no heartbeat", com, out); - this.setServerACM(2, 2, 0); // Disable heartbeat on invocations - } - - async runTestCase(adapter, proxy) - { - // Heartbeats are disabled on the server, the - // invocation should fail since heartbeats are - // expected. - try - { - await proxy.sleep(10); - test(false); - } - catch(ex) - { - await proxy.interruptSleep(); - await this.waitForClosed(); - test(this._heartbeat === 0); - } - } - } - - class InvocationHeartbeatCloseOnIdleTest extends TestCase - { - constructor(com, out) - { - super("invocation with no heartbeat and close on idle", com, out); - this.setClientACM(1, 1, 0); // Only close on idle. - this.setServerACM(1, 2, 0); // Disable heartbeat on invocations - } - - async runTestCase(adapter, proxy) - { - // No close on invocation, the call should succeed this - // time. - await proxy.sleep(3); - test(this._heartbeat === 0); - test(!this._closed); - } - } - - class CloseOnIdleTest extends TestCase - { - constructor(com, out) - { - super("close on idle", com, out); - this.setClientACM(1, 1, 0); // Only close on idle - } - - async runTestCase(adapter, proxy) - { - await Ice.Promise.delay(3000); - await this.waitForClosed(); - test(this._heartbeat === 0); - } - } - - class CloseOnInvocationTest extends TestCase - { - constructor(com, out) - { - super("close on invocation", com, out); - this.setClientACM(1, 2, 0); // Only close on invocation - } - - async runTestCase(adapter, proxy) - { - await Ice.Promise.delay(3000); - test(this._heartbeat === 0); - test(!this._closed); - } - } - - class CloseOnIdleAndInvocationTest extends TestCase - { - constructor(com, out) - { - super("close on idle and invocation", com, out); - this.setClientACM(3, 3, 0); // Only close on idle and invocation - } - - async runTestCase(adapter, proxy) - { - // - // Put the adapter on hold. The server will not respond to - // the graceful close. This allows to test whether or not - // the close is graceful or forceful. - // - await adapter.hold(); - await Ice.Promise.delay(5000); - test(this._heartbeat === 0); - test(!this._closed); // Not closed yet because of graceful close. - await adapter.activate(); - await Ice.Promise.delay(1000); - await this.waitForClosed(); // Connection should be closed this time. - } - } - - class ForcefullCloseOnIdleAndInvocationTest extends TestCase - { - constructor(com, out) - { - super("forcefull close on idle and invocation", com, out); - this.setClientACM(1, 4, 0); // Only close on idle and invocation - } - - async runTestCase(adapter, proxy) - { - await adapter.hold(); - await Ice.Promise.delay(3000); - await this.waitForClosed(); - - test(this._heartbeat === 0); - } - } - - class HeartbeatOnIdleTest extends TestCase - { - constructor(com, out) - { - super("heartbeat on idle", com, out); - this.setServerACM(1, -1, 2); // Enable server heartbeats. - } - - async runTestCase(adapter, proxy) - { - await Ice.Promise.delay(3000); - return this._heartbeat >= 3; - } - } - - class HeartbeatAlwaysTest extends TestCase - { - constructor(com, out) - { - super("heartbeat always", com, out); - this.setServerACM(1, -1, 3); // Enable server heartbeats. - } - - async runTestCase(adapter, proxy) - { - for(let i = 0; i < 10; i++) - { - await proxy.ice_ping(); - await Ice.Promise.delay(300); - } - - test(this._heartbeat >= 3); - } - } - - class HeartbeatManualTest extends TestCase - { - constructor(com, out) - { - super("manual heartbeats", com, out); - // - // Disable heartbeats. - // - this.setClientACM(10, -1, 0); - this.setServerACM(10, -1, 0); - } - - async runTestCase(adapter, proxy) - { - await proxy.startHeartbeatCount(); - const con = await proxy.ice_getConnection(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await proxy.waitForHeartbeatCount(5); - } - } - - class SetACMTest extends TestCase - { - constructor(com, out) - { - super("setACM/getACM", com, out); - this.setClientACM(15, 4, 0); - } - - async runTestCase(adapter, proxy) - { - const con = proxy.ice_getCachedConnection(); - - try - { - con.setACM(-19, undefined, undefined); - test(false); - } - catch(ex) - { - } - - let acm = con.getACM(); - test(acm.timeout === 15); - test(acm.close === Ice.ACMClose.CloseOnIdleForceful); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); - - con.setACM(undefined, undefined, undefined); - acm = con.getACM(); - test(acm.timeout === 15); - test(acm.close === Ice.ACMClose.CloseOnIdleForceful); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); - - con.setACM(1, Ice.ACMClose.CloseOnInvocationAndIdle, Ice.ACMHeartbeat.HeartbeatAlways); - acm = con.getACM(); - test(acm.timeout === 1); - test(acm.close === Ice.ACMClose.CloseOnInvocationAndIdle); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatAlways); - - await proxy.startHeartbeatCount(); - await proxy.waitForHeartbeatCount(2); - - await new Promise( - (resolve, reject) => - { - con.setCloseCallback(() => resolve()); - con.close(Ice.ConnectionClose.Gracefully); - }); - - await new Promise( - (resolve, reject) => - { - con.setCloseCallback(() => resolve()); - }); - con.setHeartbeatCallback(c => test(false)); - } - } - - class Client extends TestHelper - { - async allTests() - { - const communicator = this.communicator(); - const out = this.getWriter(); - const ref = "communicator:" + this.getTestEndpoint(); - const com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); - - const tests = []; - // - // Skip some tests with IE it opens too many connections and - // IE doesn't allow more than 6 connections. - // - if(typeof navigator !== "undefined" && - ["MSIE", "Trident/7.0", "Edge/12", "Edge/13"].some(value => navigator.userAgent.indexOf(value) !== -1)) - { - tests.push(new HeartbeatOnIdleTest(com, out)); - tests.push(new SetACMTest(com, out)); - } - else - { - tests.push(new InvocationHeartbeatTest(com, out)); - tests.push(new InvocationHeartbeatOnHoldTest(com, out)); - tests.push(new InvocationNoHeartbeatTest(com, out)); - tests.push(new InvocationHeartbeatCloseOnIdleTest(com, out)); - - tests.push(new CloseOnIdleTest(com, out)); - tests.push(new CloseOnInvocationTest(com, out)); - tests.push(new CloseOnIdleAndInvocationTest(com, out)); - tests.push(new ForcefullCloseOnIdleAndInvocationTest(com, out)); - - tests.push(new HeartbeatOnIdleTest(com, out)); - tests.push(new HeartbeatAlwaysTest(com, out)); - tests.push(new HeartbeatManualTest(com, out)); - tests.push(new SetACMTest(com, out)); - } - - await Promise.all(tests.map(test => test.init())); - await Promise.all(tests.map(test => test.start())); - for(const test of tests) - { - test.join(out); - } - await Promise.all(tests.map(test => test.destroy())); - - out.write("shutting down... "); - await com.shutdown(); - out.writeLine("ok"); - } - - async run(args) - { - let communicator; - try - { - [communicator, args] = this.initialize(args); - await this.allTests(); - } - finally - { - if(communicator) - { - await communicator.destroy(); - } - } - } - } - exports.Client = Client; - -}(typeof global !== "undefined" && typeof global.process !== "undefined" ? module : undefined, - typeof global !== "undefined" && typeof global.process !== "undefined" ? require : - (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) ? self.Ice._require : window.Ice._require, - typeof global !== "undefined" && typeof global.process !== "undefined" ? exports : - (typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope) ? self : window)); diff --git a/js/test/Ice/acm/Test.ice b/js/test/Ice/acm/Test.ice deleted file mode 100644 index 14a9c6f5cd5..00000000000 --- a/js/test/Ice/acm/Test.ice +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -[["java:package:test.Ice.acm"]] -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/js/test/typescript/Ice/acm/Client.ts b/js/test/typescript/Ice/acm/Client.ts deleted file mode 100644 index 51d59a9cae0..00000000000 --- a/js/test/typescript/Ice/acm/Client.ts +++ /dev/null @@ -1,548 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -import {Ice} from "ice"; -import {Test} from "./generated" -import {TestHelper} from "../../../Common/TestHelper" - -const test = TestHelper.test; - -interface Output -{ - writeLine(data:string):void; - write(data:string):void; -} - -class LoggerI implements Ice.Logger -{ - constructor(out:Output) - { - this._messages = []; - this._out = out; - } - - print(msg:string):void - { - this._messages.push(msg); - } - - trace(category:string, message:string):void - { - this._messages.push("[" + category + "] " + message); - } - - warning(message:string):void - { - this._messages.push("warning: " + message); - } - - error(message:string):void - { - this._messages.push("error: " + message); - } - - cloneWithPrefix(prefix:string):Ice.Logger - { - return this; - } - - getPrefix():string - { - return ""; - } - - dump():void - { - this._messages.forEach(message => this._out.writeLine(message)); - this._messages = []; - } - - _messages:Array; - _out:Output; -} - -abstract class TestCase -{ - constructor(name:string, com:Test.RemoteCommunicatorPrx, out:Output) - { - this._name = name; - this._com = com; - this._logger = new LoggerI(out); - this._msg = null; - - this._clientACMTimeout = -1; - this._clientACMClose = -1; - this._clientACMHeartbeat = -1; - - this._serverACMTimeout = -1; - this._serverACMClose = -1; - this._serverACMHeartbeat = -1; - - this._heartbeat = 0; - this._closed = false; - } - - async init() - { - const initData = new Ice.InitializationData(); - initData.properties = this._com.ice_getCommunicator().getProperties().clone(); - initData.logger = this._logger; - initData.properties.setProperty("Ice.ACM.Timeout", "2"); - if(this._clientACMTimeout >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Timeout", String(this._clientACMTimeout)); - } - if(this._clientACMClose >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Close", String(this._clientACMClose)); - } - if(this._clientACMHeartbeat >= 0) - { - initData.properties.setProperty("Ice.ACM.Client.Heartbeat", String(this._clientACMHeartbeat)); - } - this._communicator = Ice.initialize(initData); - - this._adapter = await this._com.createObjectAdapter(this._serverACMTimeout, - this._serverACMClose, - this._serverACMHeartbeat); - } - - async destroy() - { - await this._adapter.deactivate(); - await this._communicator.destroy(); - } - - join(out:Output) - { - this._logger.dump(); - out.write("testing " + this._name + "... "); - if(this._msg === null) - { - out.writeLine("ok"); - } - else - { - out.writeLine("failed! " + this._msg); - test(false); - } - } - - async start() - { - try - { - let prx = await this._adapter.getTestIntf(); - prx = Test.TestIntfPrx.uncheckedCast(this._communicator.stringToProxy(prx.toString())); - const con = await prx.ice_getConnection(); - con.setCloseCallback(connection => - { - this._closed = true; - }); - con.setHeartbeatCallback(connection => ++this._heartbeat); - await this.runTestCase(this._adapter, prx); - } - catch(ex) - { - this._msg = "unexpected exception:\n" + ex.toString() + "\n" + ex.stack; - } - } - - async waitForClosed() - { - const now = Date.now(); - while(!this._closed) - { - await Ice.Promise.delay(100); - if(Date.now() - now >= 2000) - { - test(false); // Waited for more than 2s for close, something's wrong. - } - } - } - - abstract runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx):void; - - setClientACM(timeout:number, close:number, heartbeat:number) - { - this._clientACMTimeout = timeout; - this._clientACMClose = close; - this._clientACMHeartbeat = heartbeat; - } - - setServerACM(timeout:number, close:number, heartbeat:number) - { - this._serverACMTimeout = timeout; - this._serverACMClose = close; - this._serverACMHeartbeat = heartbeat; - } - - _name:string; - _com:Test.RemoteCommunicatorPrx; - _adapter:Test.RemoteObjectAdapterPrx; - _logger:LoggerI; - _msg:string; - - _clientACMTimeout:number; - _clientACMClose:number; - _clientACMHeartbeat:number; - - _serverACMTimeout:number; - _serverACMClose:number; - _serverACMHeartbeat:number; - - _heartbeat:number; - _closed:boolean; - - _communicator:Ice.Communicator; -} - -class InvocationHeartbeatTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("invocation heartbeat", com, out); - this.setServerACM(1, -1, -1); // Faster ACM to make sure we receive enough ACM heartbeats - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await proxy.sleep(4); - test(this._heartbeat >= 4); - } -} - -class InvocationHeartbeatOnHoldTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("invocation with heartbeat on hold", com, out); - // Use default ACM configuration. - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - // When the OA is put on hold, connections shouldn't - // send heartbeats, the invocation should therefore - // fail. - try - { - await proxy.sleepAndHold(10); - test(false); - } - catch(ex) - { - await adapter.activate(); - await proxy.interruptSleep(); - await this.waitForClosed(); - } - } -} - -class InvocationNoHeartbeatTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("invocation with no heartbeat", com, out); - this.setServerACM(2, 2, 0); // Disable heartbeat on invocations - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - // Heartbeats are disabled on the server, the - // invocation should fail since heartbeats are - // expected. - try - { - await proxy.sleep(10); - test(false); - } - catch(ex) - { - await proxy.interruptSleep(); - await this.waitForClosed(); - test(this._heartbeat === 0); - } - } -} - -class InvocationHeartbeatCloseOnIdleTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("invocation with no heartbeat and close on idle", com, out); - this.setClientACM(1, 1, 0); // Only close on idle. - this.setServerACM(1, 2, 0); // Disable heartbeat on invocations - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - // No close on invocation, the call should succeed this - // time. - await proxy.sleep(3); - test(this._heartbeat === 0); - test(!this._closed); - } -} - -class CloseOnIdleTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("close on idle", com, out); - this.setClientACM(1, 1, 0); // Only close on idle - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await Ice.Promise.delay(3000); - await this.waitForClosed(); - test(this._heartbeat === 0); - } -} - -class CloseOnInvocationTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("close on invocation", com, out); - this.setClientACM(1, 2, 0); // Only close on invocation - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await Ice.Promise.delay(3000); - test(this._heartbeat === 0); - test(!this._closed); - } -} - -class CloseOnIdleAndInvocationTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("close on idle and invocation", com, out); - this.setClientACM(3, 3, 0); // Only close on idle and invocation - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - // - // Put the adapter on hold. The server will not respond to - // the graceful close. This allows to test whether or not - // the close is graceful or forceful. - // - await adapter.hold(); - await Ice.Promise.delay(5000); - test(this._heartbeat === 0); - test(!this._closed); // Not closed yet because of graceful close. - await adapter.activate(); - await Ice.Promise.delay(1000); - await this.waitForClosed(); // Connection should be closed this time. - } -} - -class ForcefullCloseOnIdleAndInvocationTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("forcefull close on idle and invocation", com, out); - this.setClientACM(1, 4, 0); // Only close on idle and invocation - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await adapter.hold(); - await Ice.Promise.delay(3000); - await this.waitForClosed(); - - test(this._heartbeat === 0); - } -} - -class HeartbeatOnIdleTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("heartbeat on idle", com, out); - this.setServerACM(1, -1, 2); // Enable server heartbeats. - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await Ice.Promise.delay(3000); - return this._heartbeat >= 3; - } -} - -class HeartbeatAlwaysTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("heartbeat always", com, out); - this.setServerACM(1, -1, 3); // Enable server heartbeats. - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - for(let i = 0; i < 10; i++) - { - await proxy.ice_ping(); - await Ice.Promise.delay(300); - } - - test(this._heartbeat >= 3); - } -} - -class HeartbeatManualTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output) - { - super("manual heartbeats", com, out); - // - // Disable heartbeats. - // - this.setClientACM(10, -1, 0); - this.setServerACM(10, -1, 0); - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - await proxy.startHeartbeatCount(); - const con = await proxy.ice_getConnection(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await con.heartbeat(); - await proxy.waitForHeartbeatCount(5); - } -} - -class SetACMTest extends TestCase -{ - constructor(com:Test.RemoteCommunicatorPrx, out:Output ) - { - super("setACM/getACM", com, out); - this.setClientACM(15, 4, 0); - } - - async runTestCase(adapter:Test.RemoteObjectAdapterPrx, proxy:Test.TestIntfPrx) - { - const con = proxy.ice_getCachedConnection(); - - try - { - con.setACM(-19, undefined, undefined); - test(false); - } - catch(ex) - { - } - - let acm = con.getACM(); - test(acm.timeout === 15); - test(acm.close === Ice.ACMClose.CloseOnIdleForceful); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); - - con.setACM(undefined, undefined, undefined); - acm = con.getACM(); - test(acm.timeout === 15); - test(acm.close === Ice.ACMClose.CloseOnIdleForceful); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatOff); - - con.setACM(1, Ice.ACMClose.CloseOnInvocationAndIdle, Ice.ACMHeartbeat.HeartbeatAlways); - acm = con.getACM(); - test(acm.timeout === 1); - test(acm.close === Ice.ACMClose.CloseOnInvocationAndIdle); - test(acm.heartbeat === Ice.ACMHeartbeat.HeartbeatAlways); - - await proxy.startHeartbeatCount(); - await proxy.waitForHeartbeatCount(2); - - await new Promise( - (resolve, reject) => - { - con.setCloseCallback(() => resolve()); - con.close(Ice.ConnectionClose.Gracefully); - }); - - await new Promise( - (resolve, reject) => - { - con.setCloseCallback(() => resolve()); - }); - con.setHeartbeatCallback(c => test(false)); - } -} - -export class Client extends TestHelper -{ - async allTests() - { - const communicator = this.communicator(); - const out = this.getWriter(); - const ref = "communicator:" + this.getTestEndpoint(); - const com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); - - const tests = []; - // - // Skip some tests with IE it opens too many connections and - // IE doesn't allow more than 6 connections. - // - if(typeof navigator !== "undefined" && - ["MSIE", "Trident/7.0", "Edge/12", "Edge/13"].some(value => navigator.userAgent.indexOf(value) !== -1)) - { - tests.push(new HeartbeatOnIdleTest(com, out)); - tests.push(new SetACMTest(com, out)); - } - else - { - tests.push(new InvocationHeartbeatTest(com, out)); - tests.push(new InvocationHeartbeatOnHoldTest(com, out)); - tests.push(new InvocationNoHeartbeatTest(com, out)); - tests.push(new InvocationHeartbeatCloseOnIdleTest(com, out)); - - tests.push(new CloseOnIdleTest(com, out)); - tests.push(new CloseOnInvocationTest(com, out)); - tests.push(new CloseOnIdleAndInvocationTest(com, out)); - tests.push(new ForcefullCloseOnIdleAndInvocationTest(com, out)); - - tests.push(new HeartbeatOnIdleTest(com, out)); - tests.push(new HeartbeatAlwaysTest(com, out)); - tests.push(new HeartbeatManualTest(com, out)); - tests.push(new SetACMTest(com, out)); - } - - await Promise.all(tests.map(test => test.init())); - await Promise.all(tests.map(test => test.start())); - for(const test of tests) - { - test.join(out); - } - await Promise.all(tests.map(test => test.destroy())); - - out.write("shutting down... "); - await com.shutdown(); - out.writeLine("ok"); - } - - async run(args:string[]) - { - let communicator:Ice.Communicator; - try - { - [communicator, args] = this.initialize(args); - await this.allTests(); - } - finally - { - if(communicator) - { - await communicator.destroy(); - } - } - } -} diff --git a/js/test/typescript/Ice/acm/Test.ice b/js/test/typescript/Ice/acm/Test.ice deleted file mode 100644 index b697132fb2d..00000000000 --- a/js/test/typescript/Ice/acm/Test.ice +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -[["js:es6-module"]] - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/matlab/lib/+Ice/ACM.m b/matlab/lib/+Ice/ACM.m deleted file mode 100644 index 953db1695b0..00000000000 --- a/matlab/lib/+Ice/ACM.m +++ /dev/null @@ -1,41 +0,0 @@ -% ACM Summary of ACM -% -% A collection of Active Connection Management configuration settings. -% -% ACM Properties: -% timeout - A timeout value in seconds. -% close - The close semantics. -% heartbeat - The heartbeat semantics. - -% Copyright (c) ZeroC, Inc. All rights reserved. -% Generated from Connection.ice by slice2matlab version 3.7.10 - -classdef ACM - properties - % timeout - A timeout value in seconds. - timeout int32 - % close - The close semantics. - close Ice.ACMClose - % heartbeat - The heartbeat semantics. - heartbeat Ice.ACMHeartbeat - end - methods - function obj = ACM(timeout, close, heartbeat) - if nargin == 0 - obj.timeout = 0; - obj.close = Ice.ACMClose.CloseOff; - obj.heartbeat = Ice.ACMHeartbeat.HeartbeatOff; - elseif ne(timeout, IceInternal.NoInit.Instance) - obj.timeout = timeout; - obj.close = close; - obj.heartbeat = heartbeat; - end - end - function r = eq(obj, other) - r = isequal(obj, other); - end - function r = ne(obj, other) - r = ~isequal(obj, other); - end - end -end diff --git a/matlab/lib/+Ice/ACMClose.m b/matlab/lib/+Ice/ACMClose.m deleted file mode 100644 index d8e91d03039..00000000000 --- a/matlab/lib/+Ice/ACMClose.m +++ /dev/null @@ -1,48 +0,0 @@ -% ACMClose Summary of ACMClose -% -% Specifies the close semantics for Active Connection Management. -% -% ACMClose Properties: -% CloseOff - Disables automatic connection closure. -% CloseOnIdle - Gracefully closes a connection that has been idle for the configured timeout period. -% CloseOnInvocation - Forcefully closes a connection that has been idle for the configured timeout period, but only if the connection has pending invocations. -% CloseOnInvocationAndIdle - Combines the behaviors of CloseOnIdle and CloseOnInvocation. -% CloseOnIdleForceful - Forcefully closes a connection that has been idle for the configured timeout period, regardless of whether the connection has pending invocations or dispatch. - -% Copyright (c) ZeroC, Inc. All rights reserved. -% Generated from Connection.ice by slice2matlab version 3.7.10 - -classdef ACMClose < uint8 - enumeration - % Disables automatic connection closure. - CloseOff (0) - % Gracefully closes a connection that has been idle for the configured timeout period. - CloseOnIdle (1) - % Forcefully closes a connection that has been idle for the configured timeout period, but only if the connection - % has pending invocations. - CloseOnInvocation (2) - % Combines the behaviors of CloseOnIdle and CloseOnInvocation. - CloseOnInvocationAndIdle (3) - % Forcefully closes a connection that has been idle for the configured timeout period, regardless of whether the - % connection has pending invocations or dispatch. - CloseOnIdleForceful (4) - end - methods(Static) - function r = ice_getValue(v) - switch v - case 0 - r = Ice.ACMClose.CloseOff; - case 1 - r = Ice.ACMClose.CloseOnIdle; - case 2 - r = Ice.ACMClose.CloseOnInvocation; - case 3 - r = Ice.ACMClose.CloseOnInvocationAndIdle; - case 4 - r = Ice.ACMClose.CloseOnIdleForceful; - otherwise - throw(Ice.MarshalException('', '', sprintf('enumerator value %d is out of range', v))); - end - end - end -end diff --git a/matlab/lib/+Ice/ACMHeartbeat.m b/matlab/lib/+Ice/ACMHeartbeat.m deleted file mode 100644 index b6a4e0fad40..00000000000 --- a/matlab/lib/+Ice/ACMHeartbeat.m +++ /dev/null @@ -1,41 +0,0 @@ -% ACMHeartbeat Summary of ACMHeartbeat -% -% Specifies the heartbeat semantics for Active Connection Management. -% -% ACMHeartbeat Properties: -% HeartbeatOff - Disables heartbeats. -% HeartbeatOnDispatch - Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. -% HeartbeatOnIdle - Send a heartbeat at regular intervals when the connection is idle. -% HeartbeatAlways - Send a heartbeat at regular intervals until the connection is closed. - -% Copyright (c) ZeroC, Inc. All rights reserved. -% Generated from Connection.ice by slice2matlab version 3.7.10 - -classdef ACMHeartbeat < uint8 - enumeration - % Disables heartbeats. - HeartbeatOff (0) - % Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. - HeartbeatOnDispatch (1) - % Send a heartbeat at regular intervals when the connection is idle. - HeartbeatOnIdle (2) - % Send a heartbeat at regular intervals until the connection is closed. - HeartbeatAlways (3) - end - methods(Static) - function r = ice_getValue(v) - switch v - case 0 - r = Ice.ACMHeartbeat.HeartbeatOff; - case 1 - r = Ice.ACMHeartbeat.HeartbeatOnDispatch; - case 2 - r = Ice.ACMHeartbeat.HeartbeatOnIdle; - case 3 - r = Ice.ACMHeartbeat.HeartbeatAlways; - otherwise - throw(Ice.MarshalException('', '', sprintf('enumerator value %d is out of range', v))); - end - end - end -end diff --git a/matlab/lib/+Ice/Connection.m b/matlab/lib/+Ice/Connection.m index 368bb773a15..d0a1745abb9 100644 --- a/matlab/lib/+Ice/Connection.m +++ b/matlab/lib/+Ice/Connection.m @@ -15,8 +15,6 @@ % connection. % heartbeat - Send a heartbeat message. % heartbeatAsync - Send a heartbeat message. - % setACM - Set the active connection management parameters. - % getACM - Get the ACM parameters. % type - Return the connection type. % timeout - Get the timeout for the connection. % toString - Return a description of the connection as human readable @@ -151,41 +149,6 @@ function heartbeat(obj) assert(~isNull(future)); r = Ice.Future(future, 'heartbeat', 0, 'Ice_SimpleFuture', @(fut) fut.iceCall('check')); end - function setACM(obj, timeout, close, heartbeat) - % setACM Set the active connection management parameters. - % - % Parameters: - % timeout (int32) - The timeout value in milliseconds. - % close (Ice.ACMClose) - The close condition. - % heartbeat (Ice.ACMHeartbeat) - The hertbeat condition. - - if timeout == Ice.Unset - timeout = []; - end - if close == Ice.Unset - close = []; - end - if heartbeat == Ice.Unset - heartbeat = []; - end - obj.iceCall('setACM', timeout, close, heartbeat); - end - function r = getACM(obj) - % getACM Get the ACM parameters. - % - % Returns (Ice.ACM) - The ACM parameters. - - r = obj.iceCallWithResult('getACM'); - if isempty(r.timeout) - r.timeout = Ice.Unset; - end - if isempty(r.close) - r.close = Ice.Unset; - end - if isempty(r.heartbeat) - r.heartbeat = Ice.Unset; - end - end function r = type(obj) % type Return the connection type. This corresponds to the % endpoint type, i.e., "tcp", "udp", etc. diff --git a/matlab/src/Connection.cpp b/matlab/src/Connection.cpp index 2b3ea7f954c..bc1ba7f3be1 100644 --- a/matlab/src/Connection.cpp +++ b/matlab/src/Connection.cpp @@ -282,62 +282,6 @@ extern "C" return 0; } - mxArray* Ice_Connection_setACM(void* self, mxArray* t, mxArray* c, mxArray* h) - { - optional timeout; - optional close; - optional heartbeat; - - try - { - if (!mxIsEmpty(t)) - { - if (!mxIsScalar(t)) - { - throw invalid_argument("scalar value required for timeout"); - } - if (!mxIsNumeric(t)) - { - throw invalid_argument("numeric value required for timeout"); - } - timeout = static_cast(mxGetScalar(t)); - } - if (!mxIsEmpty(c)) - { - close = static_cast(getEnumerator(c, "Ice.ACMClose")); - } - if (!mxIsEmpty(h)) - { - heartbeat = static_cast(getEnumerator(h, "Ice.ACMHeartbeat")); - } - deref(self)->setACM(timeout, close, heartbeat); - } - catch (...) - { - return convertException(std::current_exception()); - } - return 0; - } - - mxArray* Ice_Connection_getACM(void* self) - { - try - { - auto acm = deref(self)->getACM(); - mxArray* params[3]; - params[0] = createInt(acm.timeout); - params[1] = createInt(static_cast(acm.close)); // The integer is converted to the enumerator. - params[2] = createInt(static_cast(acm.heartbeat)); // The integer is converted to the enumerator. - mxArray* r; - mexCallMATLAB(1, &r, 3, params, "Ice.ACM"); - return createResultValue(r); - } - catch (...) - { - return createResultException(convertException(std::current_exception())); - } - } - mxArray* Ice_Connection_type(void* self) { try diff --git a/matlab/src/ice.h b/matlab/src/ice.h index b38ff40ac28..33f99b7b728 100644 --- a/matlab/src/ice.h +++ b/matlab/src/ice.h @@ -167,8 +167,6 @@ extern "C" ICE_MATLAB_API mxArray* Ice_Connection_getEndpoint(void*, void**); ICE_MATLAB_API mxArray* Ice_Connection_heartbeat(void*); ICE_MATLAB_API mxArray* Ice_Connection_heartbeatAsync(void*, void**); - ICE_MATLAB_API mxArray* Ice_Connection_setACM(void*, mxArray*, mxArray*, mxArray*); - ICE_MATLAB_API mxArray* Ice_Connection_getACM(void*); ICE_MATLAB_API mxArray* Ice_Connection_type(void*); ICE_MATLAB_API mxArray* Ice_Connection_timeout(void*); ICE_MATLAB_API mxArray* Ice_Connection_toString(void*); diff --git a/matlab/test/Ice/acm/AllTests.m b/matlab/test/Ice/acm/AllTests.m deleted file mode 100644 index e8400b2a467..00000000000 --- a/matlab/test/Ice/acm/AllTests.m +++ /dev/null @@ -1,98 +0,0 @@ -% -% Copyright (c) ZeroC, Inc. All rights reserved. -% - -classdef AllTests - methods(Static) - function allTests(helper) - import Test.*; - - communicator = helper.communicator(); - - ref = ['communicator:', helper.getTestEndpoint()]; - com = RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)); - - AllTests.testSetACM(communicator, com); - AllTests.testHeartbeatManual(communicator, com); - - com.shutdown(); - end - function testSetACM(communicator, com) - import Test.*; - - fprintf('testing setACM/getACM... '); - - adapter = com.createObjectAdapter(-1, -1, -1); - - initData = Ice.InitializationData(); - initData.properties_ = communicator.getProperties().clone(); - initData.properties_.setProperty('Ice.ACM.Timeout', '1'); - initData.properties_.setProperty('Ice.ACM.Client.Timeout', '15'); - initData.properties_.setProperty('Ice.ACM.Client.Close', '4'); - initData.properties_.setProperty('Ice.ACM.Client.Heartbeat', '2'); - testCommunicator = Ice.initialize(initData); - proxy = TestIntfPrx.uncheckedCast(testCommunicator.stringToProxy(adapter.getTestIntf().ice_toString())); - proxy.ice_getConnection(); - - try - proxy.ice_getCachedConnection().setACM(-19, Ice.Unset, Ice.Unset); - assert(false); - catch ex - end - - acm = proxy.ice_getCachedConnection().getACM(); - assert(acm.timeout == 15); - assert(acm.close == Ice.ACMClose.CloseOnIdleForceful); - assert(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOnIdle); - - proxy.ice_getCachedConnection().setACM(Ice.Unset, Ice.Unset, Ice.Unset); - acm = proxy.ice_getCachedConnection().getACM(); - assert(acm.timeout == 15); - assert(acm.close == Ice.ACMClose.CloseOnIdleForceful); - assert(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOnIdle); - - proxy.ice_getCachedConnection().setACM(1, Ice.ACMClose.CloseOnInvocationAndIdle, ... - Ice.ACMHeartbeat.HeartbeatAlways); - acm = proxy.ice_getCachedConnection().getACM(); - assert(acm.timeout == 1); - assert(acm.close == Ice.ACMClose.CloseOnInvocationAndIdle); - assert(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatAlways); - - proxy.startHeartbeatCount(); - proxy.waitForHeartbeatCount(2); - - adapter.deactivate(); - testCommunicator.destroy(); - fprintf('ok\n'); - end - function testHeartbeatManual(communicator, com) - import Test.*; - - fprintf('testing manual heartbeats... '); - - adapter = com.createObjectAdapter(10, -1, 0); - - initData = Ice.InitializationData(); - initData.properties_ = communicator.getProperties().clone(); - initData.properties_.setProperty('Ice.ACM.Timeout', '10'); - initData.properties_.setProperty('Ice.ACM.Client.Timeout', '10'); - initData.properties_.setProperty('Ice.ACM.Client.Close', '0'); - initData.properties_.setProperty('Ice.ACM.Client.Heartbeat', '0'); - testCommunicator = Ice.initialize(initData); - proxy = TestIntfPrx.uncheckedCast(testCommunicator.stringToProxy(adapter.getTestIntf().ice_toString())); - con = proxy.ice_getConnection(); - - proxy.startHeartbeatCount(); - con.heartbeat(); - con.heartbeat(); - con.heartbeat(); - con.heartbeat(); - con.heartbeat(); - proxy.waitForHeartbeatCount(5); - - adapter.deactivate(); - testCommunicator.destroy(); - fprintf('ok\n'); - end - end -end diff --git a/matlab/test/Ice/acm/Client.m b/matlab/test/Ice/acm/Client.m deleted file mode 100644 index 3b0ecaf70dd..00000000000 --- a/matlab/test/Ice/acm/Client.m +++ /dev/null @@ -1,20 +0,0 @@ -% -% Copyright (c) ZeroC, Inc. All rights reserved. -% - -function client(args) - addpath('generated'); - if ~libisloaded('ice') - loadlibrary('ice', @iceproto) - end - - helper = TestHelper(); - properties = helper.createTestProperties(args); - properties.setProperty('Ice.Warn.Connections', '0'); - communicator = helper.initialize(properties); - cleanup = onCleanup(@() communicator.destroy()); - - AllTests.allTests(helper); - - clear('classes'); % Avoids conflicts with tests that define the same symbols. -end diff --git a/matlab/test/Ice/acm/Test.ice b/matlab/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/matlab/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/php/lib/IceLocal/Connection.php b/php/lib/IceLocal/Connection.php index 69601fd1210..e9eb89bfda2 100644 --- a/php/lib/IceLocal/Connection.php +++ b/php/lib/IceLocal/Connection.php @@ -63,67 +63,6 @@ public function heartbeat($con); $Ice__t_HeartbeatCallback = IcePHP_defineClass('::Ice::HeartbeatCallback', '\\Ice\\HeartbeatCallback', -1, true, null, null); } -namespace Ice -{ - global $Ice__t_ACMClose; - class ACMClose - { - const CloseOff = 0; - const CloseOnIdle = 1; - const CloseOnInvocation = 2; - const CloseOnInvocationAndIdle = 3; - const CloseOnIdleForceful = 4; - } - - $Ice__t_ACMClose = IcePHP_defineEnum('::Ice::ACMClose', array('CloseOff', 0, 'CloseOnIdle', 1, 'CloseOnInvocation', 2, 'CloseOnInvocationAndIdle', 3, 'CloseOnIdleForceful', 4)); -} - -namespace Ice -{ - global $Ice__t_ACMHeartbeat; - class ACMHeartbeat - { - const HeartbeatOff = 0; - const HeartbeatOnDispatch = 1; - const HeartbeatOnIdle = 2; - const HeartbeatAlways = 3; - } - - $Ice__t_ACMHeartbeat = IcePHP_defineEnum('::Ice::ACMHeartbeat', array('HeartbeatOff', 0, 'HeartbeatOnDispatch', 1, 'HeartbeatOnIdle', 2, 'HeartbeatAlways', 3)); -} - -namespace Ice -{ - global $Ice__t_ACM; - class ACM - { - public function __construct($timeout=0, $close=\Ice\ACMClose::CloseOff, $heartbeat=\Ice\ACMHeartbeat::HeartbeatOff) - { - $this->timeout = $timeout; - $this->close = $close; - $this->heartbeat = $heartbeat; - } - - public function __toString(): string - { - global $Ice__t_ACM; - return IcePHP_stringify($this, $Ice__t_ACM); - } - - public $timeout; - public $close; - public $heartbeat; - } - - global $IcePHP__t_int; - global $Ice__t_ACMClose; - global $Ice__t_ACMHeartbeat; - $Ice__t_ACM = IcePHP_defineStruct('::Ice::ACM', '\\Ice\\ACM', array( - array('timeout', $IcePHP__t_int), - array('close', $Ice__t_ACMClose), - array('heartbeat', $Ice__t_ACMHeartbeat))); -} - namespace Ice { global $Ice__t_ConnectionClose; diff --git a/php/src/Connection.cpp b/php/src/Connection.cpp index 9f8dbf95c3d..63245356c71 100644 --- a/php/src/Connection.cpp +++ b/php/src/Connection.cpp @@ -175,103 +175,6 @@ ZEND_METHOD(Ice_Connection, heartbeat) } } -ZEND_BEGIN_ARG_INFO_EX(Ice_Connection_setACM_arginfo, 1, ZEND_RETURN_VALUE, static_cast(3)) -ZEND_ARG_INFO(0, timeout) -ZEND_ARG_INFO(0, close) -ZEND_ARG_INFO(0, heartbeat) -ZEND_END_ARG_INFO() - -ZEND_METHOD(Ice_Connection, setACM) -{ - Ice::ConnectionPtr _this = Wrapper::value(getThis()); - assert(_this); - - zval* t; - zval* c; - zval* h; - if (zend_parse_parameters(ZEND_NUM_ARGS(), const_cast("zzz"), &t, &c, &h) != SUCCESS) - { - RETURN_NULL(); - } - - optional timeout; - optional close; - optional heartbeat; - - if (!isUnset(t)) - { - if (Z_TYPE_P(t) != IS_LONG) - { - invalidArgument("value for 'timeout' argument must be Unset or an integer"); - RETURN_NULL(); - } - timeout = static_cast(Z_LVAL_P(t)); - } - - if (!isUnset(c)) - { - if (Z_TYPE_P(c) != IS_LONG) - { - invalidArgument("value for 'close' argument must be Unset or an enumerator of ACMClose"); - RETURN_NULL(); - } - close = static_cast(Z_LVAL_P(c)); - } - - if (!isUnset(h)) - { - if (Z_TYPE_P(h) != IS_LONG) - { - invalidArgument("value for 'heartbeat' argument must be Unset or an enumerator of ACMHeartbeat"); - RETURN_NULL(); - } - heartbeat = static_cast(Z_LVAL_P(h)); - } - - try - { - _this->setACM(timeout, close, heartbeat); - } - catch (...) - { - throwException(current_exception()); - RETURN_NULL(); - } -} - -ZEND_METHOD(Ice_Connection, getACM) -{ - if (ZEND_NUM_ARGS() > 0) - { - WRONG_PARAM_COUNT; - } - - Ice::ConnectionPtr _this = Wrapper::value(getThis()); - assert(_this); - - try - { - Ice::ACM acm = _this->getACM(); - - zend_class_entry* acmClass = idToClass("::Ice::ACM"); - - if (object_init_ex(return_value, const_cast(acmClass)) != SUCCESS) - { - runtimeError("unable to initialize object of type %s", acmClass->name); - RETURN_NULL(); - } - - add_property_long(return_value, "timeout", static_cast(acm.timeout)); - add_property_long(return_value, "close", static_cast(acm.close)); - add_property_long(return_value, "heartbeat", static_cast(acm.heartbeat)); - } - catch (...) - { - throwException(current_exception()); - RETURN_NULL(); - } -} - ZEND_METHOD(Ice_Connection, type) { if (ZEND_NUM_ARGS() > 0) @@ -440,23 +343,19 @@ static zend_function_entry _connectionClassMethods[] = { __toString, ice_to_string_arginfo, ZEND_ACC_PUBLIC) ZEND_ME(Ice_Connection, close, Ice_Connection_close_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, getEndpoint, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, flushBatchRequests, Ice_Connection_flushBatchRequests_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, heartbeat, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, setACM, Ice_Connection_setACM_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, getACM, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, type, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, timeout, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, toString, ice_void_arginfo, ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, getInfo, ice_void_arginfo, ZEND_ACC_PUBLIC) ZEND_ME( - Ice_Connection, - setBufferSize, - Ice_Connection_setBufferSize_arginfo, - ZEND_ACC_PUBLIC) - ZEND_ME(Ice_Connection, throwException, ice_void_arginfo, ZEND_ACC_PUBLIC){ - 0, - 0, - 0}}; + ZEND_ME(Ice_Connection, getEndpoint, ice_void_arginfo, ZEND_ACC_PUBLIC) ZEND_ME( + Ice_Connection, + flushBatchRequests, + Ice_Connection_flushBatchRequests_arginfo, + ZEND_ACC_PUBLIC) ZEND_ME(Ice_Connection, heartbeat, ice_void_arginfo, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, type, ice_void_arginfo, ZEND_ACC_PUBLIC) ZEND_ME( + Ice_Connection, + timeout, + ice_void_arginfo, + ZEND_ACC_PUBLIC) ZEND_ME(Ice_Connection, toString, ice_void_arginfo, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, getInfo, ice_void_arginfo, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, setBufferSize, Ice_Connection_setBufferSize_arginfo, ZEND_ACC_PUBLIC) + ZEND_ME(Ice_Connection, throwException, ice_void_arginfo, ZEND_ACC_PUBLIC){0, 0, 0}}; ZEND_METHOD(Ice_ConnectionInfo, __construct) { runtimeError("ConnectionInfo cannot be instantiated"); } diff --git a/php/test/Ice/acm/.gitignore b/php/test/Ice/acm/.gitignore deleted file mode 100644 index bed01730acc..00000000000 --- a/php/test/Ice/acm/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Test.php diff --git a/php/test/Ice/acm/Client.php b/php/test/Ice/acm/Client.php deleted file mode 100644 index eb5c0573fa2..00000000000 --- a/php/test/Ice/acm/Client.php +++ /dev/null @@ -1,109 +0,0 @@ -createObjectAdapter(-1, -1, -1); - - $communicator = $helper->communicator(); - $properties = $communicator->getProperties()->clone(); - $properties->setProperty("Ice.ACM.Timeout", "1"); - $properties->setProperty("Ice.ACM.Client.Timeout", "15"); - $properties->setProperty("Ice.ACM.Client.Close", "4"); - $properties->setProperty("Ice.ACM.Client.Heartbeat", "2"); - - $communicator = $helper->initialize($properties); - - $proxy = $communicator->stringToProxy( - $adapter->getTestIntf()->ice_toString())->ice_uncheckedCast("::Test::TestIntf"); - $proxy->ice_getConnection(); - - $acm = $proxy->ice_getCachedConnection()->getACM(); - test($acm->timeout == 15); - test($acm->close == Ice\ACMClose::CloseOnIdleForceful); - test($acm->heartbeat == Ice\ACMHeartbeat::HeartbeatOnIdle); - - $proxy->ice_getCachedConnection()->setACM(Ice\None, Ice\None, Ice\None); - $acm = $proxy->ice_getCachedConnection()->getACM(); - test($acm->timeout == 15); - test($acm->close == Ice\ACMClose::CloseOnIdleForceful); - test($acm->heartbeat == Ice\ACMHeartbeat::HeartbeatOnIdle); - - $proxy->ice_getCachedConnection()->setACM(1, Ice\ACMClose::CloseOnInvocationAndIdle, Ice\ACMHeartbeat::HeartbeatAlways); - $acm = $proxy->ice_getCachedConnection()->getACM(); - test($acm->timeout == 1); - test($acm->close == Ice\ACMClose::CloseOnInvocationAndIdle); - test($acm->heartbeat == Ice\ACMHeartbeat::HeartbeatAlways); - - $proxy->startHeartbeatCount(); - $proxy->waitForHeartbeatCount(2); - - $adapter->deactivate(); - $communicator->destroy(); - echo "ok\n"; -} - -function testHeartbeatManual($helper, $com) -{ - echo "testing manual heartbeats... "; - flush(); - - $adapter = $com->createObjectAdapter(10, -1, 0); - - $communicator = $helper->communicator(); - $properties = $communicator->getProperties()->clone(); - $properties->setProperty("Ice.ACM.Timeout", "10"); - $properties->setProperty("Ice.ACM.Client.Timeout", "10"); - $properties->setProperty("Ice.ACM.Client.Close", "0"); - $properties->setProperty("Ice.ACM.Client.Heartbeat", "0"); - $communicator = $helper->initialize($properties); - $proxy = $communicator->stringToProxy( - $adapter->getTestIntf()->ice_toString())->ice_uncheckedCast("::Test::TestIntf"); - $con = $proxy->ice_getConnection(); - - $proxy->startHeartbeatCount(); - $con->heartbeat(); - $con->heartbeat(); - $con->heartbeat(); - $con->heartbeat(); - $con->heartbeat(); - $proxy->waitForHeartbeatCount(5); - - $adapter->deactivate(); - $communicator->destroy(); - echo "ok\n"; -} - -class Client extends TestHelper -{ - function run($args) - { - try - { - $communicator = $this->initialize($args); - $ref = sprintf("communicator:%s", $this->getTestEndpoint()); - $com = $communicator->stringToProxy($ref)->ice_uncheckedCast("::Test::RemoteCommunicator"); - - testSetACM($this, $com); - testHeartbeatManual($this, $com); - - $com->shutdown(); - $communicator->destroy(); - } - catch(Exception $ex) - { - $communicator->destroy(); - throw $ex; - } - } -} -?> diff --git a/php/test/Ice/acm/Test.ice b/php/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/php/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/python/modules/IcePy/Connection.cpp b/python/modules/IcePy/Connection.cpp index 2c289219f3a..9adcab2eac3 100644 --- a/python/modules/IcePy/Connection.cpp +++ b/python/modules/IcePy/Connection.cpp @@ -590,155 +590,6 @@ extern "C" return Py_None; } -#ifdef WIN32 -extern "C" -#endif - static PyObject* - connectionSetACM(ConnectionObject* self, PyObject* args) -{ - assert(self->connection); - - optional timeout; - optional close; - optional heartbeat; - - PyObject* acmCloseType = lookupType("Ice.ACMClose"); - PyObject* acmHeartbeatType = lookupType("Ice.ACMHeartbeat"); - PyObject* t; - PyObject* c; - PyObject* h; - if (!PyArg_ParseTuple(args, STRCAST("OOO"), &t, &c, &h)) - { - return 0; - } - - if (t != Unset) - { - timeout = static_cast(PyLong_AsLong(t)); - if (PyErr_Occurred()) - { - return 0; - } - } - - if (c != Unset) - { - if (PyObject_IsInstance(c, acmCloseType) == 0) - { - PyErr_Format(PyExc_TypeError, "value for 'close' argument must be Unset or an enumerator of Ice.ACMClose"); - return 0; - } - PyObjectHandle v = getAttr(c, "_value", true); - assert(v.get()); - close = static_cast(PyLong_AsLong(v.get())); - } - - if (h != Unset) - { - if (PyObject_IsInstance(h, acmHeartbeatType) == 0) - { - PyErr_Format( - PyExc_TypeError, - "value for 'heartbeat' argument must be Unset or an enumerator of Ice.ACMHeartbeat"); - return 0; - } - PyObjectHandle v = getAttr(h, "_value", true); - assert(v.get()); - heartbeat = static_cast(PyLong_AsLong(v.get())); - } - - try - { - (*self->connection)->setACM(timeout, close, heartbeat); - } - catch (const invalid_argument& ex) - { - PyErr_Format(PyExc_RuntimeError, "%s", ex.what()); - return 0; - } - catch (...) - { - setPythonException(current_exception()); - return 0; - } - - Py_INCREF(Py_None); - return Py_None; -} - -#ifdef WIN32 -extern "C" -#endif - static PyObject* - connectionGetACM(ConnectionObject* self, PyObject* /*args*/) -{ - assert(self->connection); - - PyObject* acmType = lookupType("Ice.ACM"); - PyObject* acmCloseType = lookupType("Ice._t_ACMClose"); - PyObject* acmHeartbeatType = lookupType("Ice._t_ACMHeartbeat"); - Ice::ACM acm; - - try - { - acm = (*self->connection)->getACM(); - } - catch (...) - { - setPythonException(current_exception()); - return 0; - } - - PyObjectHandle r = StructInfo::instantiate(acmType); - if (!r.get()) - { - return 0; - } - - PyObjectHandle timeout = PyLong_FromLong(acm.timeout); - if (!timeout.get()) - { - assert(PyErr_Occurred()); - return 0; - } - - if (PyObject_SetAttrString(r.get(), STRCAST("timeout"), timeout.get()) < 0) - { - assert(PyErr_Occurred()); - return 0; - } - - EnumInfoPtr acmCloseEnum = dynamic_pointer_cast(getType(acmCloseType)); - assert(acmCloseEnum); - PyObjectHandle close = acmCloseEnum->enumeratorForValue(static_cast(acm.close)); - if (!close.get()) - { - PyErr_Format(PyExc_ValueError, "unexpected value for 'close' member of Ice.ACM"); - return 0; - } - if (PyObject_SetAttrString(r.get(), STRCAST("close"), close.get()) < 0) - { - assert(PyErr_Occurred()); - return 0; - } - - EnumInfoPtr acmHeartbeatEnum = dynamic_pointer_cast(getType(acmHeartbeatType)); - assert(acmHeartbeatEnum); - PyObjectHandle heartbeat = acmHeartbeatEnum->enumeratorForValue(static_cast(acm.heartbeat)); - if (!heartbeat.get()) - { - PyErr_Format(PyExc_ValueError, "unexpected value for 'heartbeat' member of Ice.ACM"); - return 0; - } - if (PyObject_SetAttrString(r.get(), STRCAST("heartbeat"), heartbeat.get()) < 0) - { - assert(PyErr_Occurred()); - return 0; - } - - return r.release(); -} - #ifdef WIN32 extern "C" #endif @@ -926,14 +777,6 @@ static PyMethodDef ConnectionMethods[] = { reinterpret_cast(connectionHeartbeat), METH_NOARGS, PyDoc_STR(STRCAST("heartbeat() -> None"))}, - {STRCAST("setACM"), - reinterpret_cast(connectionSetACM), - METH_VARARGS, - PyDoc_STR(STRCAST("setACM(int, Ice.ACMClose, Ice.ACMHeartbeat) -> None"))}, - {STRCAST("getACM"), - reinterpret_cast(connectionGetACM), - METH_NOARGS, - PyDoc_STR(STRCAST("getACM() -> Ice.ACM"))}, {STRCAST("type"), reinterpret_cast(connectionType), METH_NOARGS, diff --git a/python/python/Glacier2/__init__.py b/python/python/Glacier2/__init__.py index a6421a773b2..9e0ed07fd9c 100644 --- a/python/python/Glacier2/__init__.py +++ b/python/python/Glacier2/__init__.py @@ -147,22 +147,18 @@ def doMainInternal(self, args, initData): status = 1 if sessionCreated: - acmTimeout = 0 + remoteIdleTimeout = 0 try: - acmTimeout = Application._router.getACMTimeout() + remoteIdleTimeout = Application._router.getACMTimeout() except Ice.OperationNotExistException: pass - if acmTimeout <= 0: - acmTimeout = Application._router.getSessionTimeout() - if acmTimeout > 0: - connection = Application._router.ice_getCachedConnection() - assert connection - connection.setACM( - acmTimeout, Ice.Unset, Ice.ACMHeartbeat.HeartbeatAlways - ) - connection.setCloseCallback( - lambda conn: self.sessionDestroyed() - ) + if remoteIdleTimeout <= 0: + remoteIdleTimeout = Application._router.getSessionTimeout() + # TODO: verify that the local idle timeout is compatible with the remote idle timeout. + connection = Application._router.ice_getCachedConnection() + assert connection + connection.setCloseCallback( + lambda conn: self.sessionDestroyed()) Application._category = Application._router.getCategoryForClient() status = self.runWithSession(args) diff --git a/python/python/Ice/Connection_local.py b/python/python/Ice/Connection_local.py index 1b5cf1158b8..6603a71881f 100644 --- a/python/python/Ice/Connection_local.py +++ b/python/python/Ice/Connection_local.py @@ -182,214 +182,6 @@ def __str__(self): _M_Ice.HeartbeatCallback = HeartbeatCallback del HeartbeatCallback -if "ACMClose" not in _M_Ice.__dict__: - _M_Ice.ACMClose = Ice.createTempClass() - - class ACMClose(Ice.EnumBase): - """ - Specifies the close semantics for Active Connection Management. - Enumerators: - CloseOff -- Disables automatic connection closure. - CloseOnIdle -- Gracefully closes a connection that has been idle for the configured timeout period. - CloseOnInvocation -- Forcefully closes a connection that has been idle for the configured timeout period, but only if the connection - has pending invocations. - CloseOnInvocationAndIdle -- Combines the behaviors of CloseOnIdle and CloseOnInvocation. - CloseOnIdleForceful -- Forcefully closes a connection that has been idle for the configured timeout period, regardless of whether the - connection has pending invocations or dispatch. - """ - - def __init__(self, _n, _v): - Ice.EnumBase.__init__(self, _n, _v) - - def valueOf(self, _n): - if _n in self._enumerators: - return self._enumerators[_n] - return None - - valueOf = classmethod(valueOf) - - ACMClose.CloseOff = ACMClose("CloseOff", 0) - ACMClose.CloseOnIdle = ACMClose("CloseOnIdle", 1) - ACMClose.CloseOnInvocation = ACMClose("CloseOnInvocation", 2) - ACMClose.CloseOnInvocationAndIdle = ACMClose("CloseOnInvocationAndIdle", 3) - ACMClose.CloseOnIdleForceful = ACMClose("CloseOnIdleForceful", 4) - ACMClose._enumerators = { - 0: ACMClose.CloseOff, - 1: ACMClose.CloseOnIdle, - 2: ACMClose.CloseOnInvocation, - 3: ACMClose.CloseOnInvocationAndIdle, - 4: ACMClose.CloseOnIdleForceful, - } - - _M_Ice._t_ACMClose = IcePy.defineEnum( - "::Ice::ACMClose", ACMClose, (), ACMClose._enumerators - ) - - _M_Ice.ACMClose = ACMClose - del ACMClose - -if "ACMHeartbeat" not in _M_Ice.__dict__: - _M_Ice.ACMHeartbeat = Ice.createTempClass() - - class ACMHeartbeat(Ice.EnumBase): - """ - Specifies the heartbeat semantics for Active Connection Management. - Enumerators: - HeartbeatOff -- Disables heartbeats. - HeartbeatOnDispatch -- Send a heartbeat at regular intervals if the connection is idle and only if there are pending dispatch. - HeartbeatOnIdle -- Send a heartbeat at regular intervals when the connection is idle. - HeartbeatAlways -- Send a heartbeat at regular intervals until the connection is closed. - """ - - def __init__(self, _n, _v): - Ice.EnumBase.__init__(self, _n, _v) - - def valueOf(self, _n): - if _n in self._enumerators: - return self._enumerators[_n] - return None - - valueOf = classmethod(valueOf) - - ACMHeartbeat.HeartbeatOff = ACMHeartbeat("HeartbeatOff", 0) - ACMHeartbeat.HeartbeatOnDispatch = ACMHeartbeat("HeartbeatOnDispatch", 1) - ACMHeartbeat.HeartbeatOnIdle = ACMHeartbeat("HeartbeatOnIdle", 2) - ACMHeartbeat.HeartbeatAlways = ACMHeartbeat("HeartbeatAlways", 3) - ACMHeartbeat._enumerators = { - 0: ACMHeartbeat.HeartbeatOff, - 1: ACMHeartbeat.HeartbeatOnDispatch, - 2: ACMHeartbeat.HeartbeatOnIdle, - 3: ACMHeartbeat.HeartbeatAlways, - } - - _M_Ice._t_ACMHeartbeat = IcePy.defineEnum( - "::Ice::ACMHeartbeat", ACMHeartbeat, (), ACMHeartbeat._enumerators - ) - - _M_Ice.ACMHeartbeat = ACMHeartbeat - del ACMHeartbeat - -if "ACM" not in _M_Ice.__dict__: - _M_Ice.ACM = Ice.createTempClass() - - class ACM(object): - """ - A collection of Active Connection Management configuration settings. - Members: - timeout -- A timeout value in seconds. - close -- The close semantics. - heartbeat -- The heartbeat semantics. - """ - - def __init__( - self, - timeout=0, - close=_M_Ice.ACMClose.CloseOff, - heartbeat=_M_Ice.ACMHeartbeat.HeartbeatOff, - ): - self.timeout = timeout - self.close = close - self.heartbeat = heartbeat - - def __hash__(self): - _h = 0 - _h = 5 * _h + Ice.getHash(self.timeout) - _h = 5 * _h + Ice.getHash(self.close) - _h = 5 * _h + Ice.getHash(self.heartbeat) - return _h % 0x7FFFFFFF - - def __compare(self, other): - if other is None: - return 1 - elif not isinstance(other, _M_Ice.ACM): - return NotImplemented - else: - if self.timeout is None or other.timeout is None: - if self.timeout != other.timeout: - return -1 if self.timeout is None else 1 - else: - if self.timeout < other.timeout: - return -1 - elif self.timeout > other.timeout: - return 1 - if self.close is None or other.close is None: - if self.close != other.close: - return -1 if self.close is None else 1 - else: - if self.close < other.close: - return -1 - elif self.close > other.close: - return 1 - if self.heartbeat is None or other.heartbeat is None: - if self.heartbeat != other.heartbeat: - return -1 if self.heartbeat is None else 1 - else: - if self.heartbeat < other.heartbeat: - return -1 - elif self.heartbeat > other.heartbeat: - return 1 - return 0 - - def __lt__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r < 0 - - def __le__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r <= 0 - - def __gt__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r > 0 - - def __ge__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r >= 0 - - def __eq__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r == 0 - - def __ne__(self, other): - r = self.__compare(other) - if r is NotImplemented: - return r - else: - return r != 0 - - def __str__(self): - return IcePy.stringify(self, _M_Ice._t_ACM) - - __repr__ = __str__ - - _M_Ice._t_ACM = IcePy.defineStruct( - "::Ice::ACM", - ACM, - (), - ( - ("timeout", (), IcePy._t_int), - ("close", (), _M_Ice._t_ACMClose), - ("heartbeat", (), _M_Ice._t_ACMHeartbeat), - ), - ) - - _M_Ice.ACM = ACM - del ACM if "ConnectionClose" not in _M_Ice.__dict__: _M_Ice.ConnectionClose = Ice.createTempClass() @@ -521,23 +313,6 @@ def heartbeat(self): """ raise NotImplementedError("method 'heartbeat' not implemented") - def setACM(self, timeout, close, heartbeat): - """ - Set the active connection management parameters. - Arguments: - timeout -- The timeout value in seconds, must be >= 0. - close -- The close condition - heartbeat -- The hertbeat condition - """ - raise NotImplementedError("method 'setACM' not implemented") - - def getACM(self): - """ - Get the ACM parameters. - Returns: The ACM parameters. - """ - raise NotImplementedError("method 'getACM' not implemented") - def type(self): """ Return the connection type. This corresponds to the endpoint type, i.e., "tcp", "udp", etc. diff --git a/python/test/Ice/acm/AllTests.py b/python/test/Ice/acm/AllTests.py deleted file mode 100644 index 2781cf8c4c0..00000000000 --- a/python/test/Ice/acm/AllTests.py +++ /dev/null @@ -1,400 +0,0 @@ -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -import Ice -import Test -import sys -import threading -import time -import traceback - - -def test(b): - if not b: - raise RuntimeError("test assertion failed") - - -class LoggerI(Ice.Logger): - def __init__(self): - self._started = False - self._messages = [] - self.m = threading.Lock() - - def start(self): - with self.m: - self._started = True - self.dump() - - def _print(self, msg): - with self.m: - self._messages.append(msg) - if self._started: - self.dump() - - def trace(self, category, msg): - with self.m: - self._messages.append("[" + category + "] " + msg) - if self._started: - self.dump() - - def warning(self, msg): - with self.m: - self._messages.append("warning: " + msg) - if self._started: - self.dump() - - def error(self, msg): - with self.m: - self._messages.append("error: " + msg) - if self._started: - self.dump() - - def getPrefix(self): - return "" - - def cloneWithPrefix(self, prefix): - return self - - def dump(self): - for p in self._messages: - print(p) - self._messages = [] - - -class TestCase(threading.Thread): - def __init__(self, name, com): - threading.Thread.__init__(self) - self._name = name - self._com = com - self._logger = LoggerI() - self._clientACMTimeout = -1 - self._clientACMClose = -1 - self._clientACMHeartbeat = -1 - self._serverACMTimeout = -1 - self._serverACMClose = -1 - self._serverACMHeartbeat = -1 - self._heartbeat = 0 - self._closed = False - self._msg = "" - self.m = threading.Condition() - - def init(self): - self._adapter = self._com.createObjectAdapter( - self._serverACMTimeout, self._serverACMClose, self._serverACMHeartbeat - ) - - initData = Ice.InitializationData() - initData.properties = self._com.ice_getCommunicator().getProperties().clone() - initData.logger = self._logger - initData.properties.setProperty("Ice.ACM.Timeout", "2") - if self._clientACMTimeout >= 0: - initData.properties.setProperty( - "Ice.ACM.Client.Timeout", str(self._clientACMTimeout) - ) - if self._clientACMClose >= 0: - initData.properties.setProperty( - "Ice.ACM.Client.Close", str(self._clientACMClose) - ) - if self._clientACMHeartbeat >= 0: - initData.properties.setProperty( - "Ice.ACM.Client.Heartbeat", str(self._clientACMHeartbeat) - ) - # initData.properties.setProperty("Ice.Trace.Protocol", "2") - # initData.properties.setProperty("Ice.Trace.Network", "2") - self._communicator = Ice.initialize(initData) - - def destroy(self): - self._adapter.deactivate() - self._communicator.destroy() - - def joinWithThread(self): - sys.stdout.write("testing " + self._name + "... ") - sys.stdout.flush() - self._logger.start() - self.join() - if len(self._msg) == 0: - print("ok") - else: - print("failed!\n" + self._msg) - test(False) - - def run(self): - proxy = Test.TestIntfPrx.uncheckedCast( - self._communicator.stringToProxy(self._adapter.getTestIntf().ice_toString()) - ) - try: - proxy.ice_getConnection().setCloseCallback(lambda conn: self.closed(conn)) - proxy.ice_getConnection().setHeartbeatCallback( - lambda conn: self.heartbeat(conn) - ) - - self.runTestCase(self._adapter, proxy) - except Exception: - self._msg = "unexpected exception:\n" + traceback.format_exc() - - def heartbeat(self, con): - with self.m: - self._heartbeat = self._heartbeat + 1 - - def closed(self, con): - with self.m: - self._closed = True - self.m.notify() - - def waitForClosed(self): - with self.m: - while not self._closed: - now = time.time() - self.m.wait(30.0) # Wait 30s - if time.time() - now > 30.0: - test(False) - - def runTestCase(self, adapter, proxy): - test(False) - - def setClientACM(self, timeout, close, heartbeat): - self._clientACMTimeout = timeout - self._clientACMClose = close - self._clientACMHeartbeat = heartbeat - - def setServerACM(self, timeout, close, heartbeat): - self._serverACMTimeout = timeout - self._serverACMClose = close - self._serverACMHeartbeat = heartbeat - - -def allTests(helper, communicator): - ref = "communicator:{0}".format(helper.getTestEndpoint(num=0)) - com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)) - - tests = [] - - class InvocationHeartbeatTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "invocation heartbeat", com) - self.setServerACM( - 1, -1, -1 - ) # Faster ACM to make sure we receive enough ACM heartbeats - - def runTestCase(self, adapter, proxy): - proxy.sleep(4) - - with self.m: - test(self._heartbeat >= 4) - - class InvocationHeartbeatOnHoldTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "invocation with heartbeat on hold", com) - # Use default ACM configuration. - - def runTestCase(self, adapter, proxy): - try: - # When the OA is put on hold, connections shouldn't - # send heartbeats, the invocation should therefore - # fail. - proxy.sleepAndHold(10) - test(False) - except Ice.ConnectionTimeoutException: - adapter.activate() - proxy.interruptSleep() - self.waitForClosed() - - class InvocationNoHeartbeatTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "invocation with no heartbeat", com) - self.setServerACM(2, 2, 0) # Disable heartbeat on invocations - - def runTestCase(self, adapter, proxy): - try: - # Heartbeats are disabled on the server, the - # invocation should fail since heartbeats are - # expected. - proxy.sleep(10) - test(False) - except Ice.ConnectionTimeoutException: - proxy.interruptSleep() - self.waitForClosed() - - with self.m: - test(self._heartbeat == 0) - - class InvocationHeartbeatCloseOnIdleTest(TestCase): - def __init__(self, com): - TestCase.__init__( - self, "invocation with no heartbeat and close on idle", com - ) - self.setClientACM(1, 1, 0) # Only close on idle. - self.setServerACM(1, 2, 0) # Disable heartbeat on invocations - - def runTestCase(self, adapter, proxy): - # No close on invocation, the call should succeed this time. - proxy.sleep(3) - - with self.m: - test(self._heartbeat == 0) - test(not self._closed) - - class CloseOnIdleTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "close on idle", com) - self.setClientACM(1, 1, 0) # Only close on idle. - - def runTestCase(self, adapter, proxy): - self.waitForClosed() - - with self.m: - test(self._heartbeat == 0) - - class CloseOnInvocationTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "close on invocation", com) - self.setClientACM(1, 2, 0) # Only close on invocation. - - def runTestCase(self, adapter, proxy): - time.sleep(3) # Idle for 3 seconds - - with self.m: - test(self._heartbeat == 0) - test(not self._closed) - - class CloseOnIdleAndInvocationTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "close on idle and invocation", com) - self.setClientACM(3, 3, 0) # Only close on idle and invocation. - - def runTestCase(self, adapter, proxy): - # - # Put the adapter on hold. The server will not respond to - # the graceful close. This allows to test whether or not - # the close is graceful or forceful. - # - adapter.hold() - time.sleep(5) # Idle for 5 seconds - - with self.m: - test(self._heartbeat == 0) - test(not self._closed) # Not closed yet because of graceful close. - - adapter.activate() - self.waitForClosed() - - class ForcefulCloseOnIdleAndInvocationTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "forceful close on idle and invocation", com) - self.setClientACM(1, 4, 0) # Only close on idle and invocation. - - def runTestCase(self, adapter, proxy): - adapter.hold() - self.waitForClosed() - - with self.m: - test(self._heartbeat == 0) - - class HeartbeatOnIdleTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "heartbeat on idle", com) - self.setServerACM(1, -1, 2) # Enable server heartbeats. - - def runTestCase(self, adapter, proxy): - time.sleep(3) - - with self.m: - test(self._heartbeat >= 3) - - class HeartbeatAlwaysTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "heartbeat always", com) - self.setServerACM(1, -1, 3) # Enable server heartbeats. - - def runTestCase(self, adapter, proxy): - for i in range(0, 10): - proxy.ice_ping() - time.sleep(0.3) - - with self.m: - test(self._heartbeat >= 3) - - class HeartbeatManualTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "manual heartbeats", com) - # - # Disable heartbeats. - # - self.setClientACM(10, -1, 0) - self.setServerACM(10, -1, 0) - - def runTestCase(self, adapter, proxy): - proxy.startHeartbeatCount() - con = proxy.ice_getConnection() - con.heartbeat() - con.heartbeat() - con.heartbeat() - con.heartbeat() - con.heartbeat() - proxy.waitForHeartbeatCount(5) - - class SetACMTest(TestCase): - def __init__(self, com): - TestCase.__init__(self, "setACM/getACM", com) - self.setClientACM(15, 4, 0) - - def runTestCase(self, adapter, proxy): - try: - proxy.ice_getCachedConnection().setACM(-19, Ice.Unset, Ice.Unset) - test(False) - except RuntimeError: - pass - - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 15) - test(acm.close == Ice.ACMClose.CloseOnIdleForceful) - test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOff) - - proxy.ice_getCachedConnection().setACM(Ice.Unset, Ice.Unset, Ice.Unset) - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 15) - test(acm.close == Ice.ACMClose.CloseOnIdleForceful) - test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOff) - - proxy.ice_getCachedConnection().setACM( - 1, - Ice.ACMClose.CloseOnInvocationAndIdle, - Ice.ACMHeartbeat.HeartbeatAlways, - ) - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 1) - test(acm.close == Ice.ACMClose.CloseOnInvocationAndIdle) - test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatAlways) - - proxy.startHeartbeatCount() - proxy.waitForHeartbeatCount(2) - - tests.append(InvocationHeartbeatTest(com)) - tests.append(InvocationHeartbeatOnHoldTest(com)) - tests.append(InvocationNoHeartbeatTest(com)) - tests.append(InvocationHeartbeatCloseOnIdleTest(com)) - - tests.append(CloseOnIdleTest(com)) - tests.append(CloseOnInvocationTest(com)) - tests.append(CloseOnIdleAndInvocationTest(com)) - tests.append(ForcefulCloseOnIdleAndInvocationTest(com)) - - tests.append(HeartbeatOnIdleTest(com)) - tests.append(HeartbeatAlwaysTest(com)) - tests.append(HeartbeatManualTest(com)) - tests.append(SetACMTest(com)) - - for p in tests: - p.init() - for p in tests: - p.start() - for p in tests: - p.joinWithThread() - for p in tests: - p.destroy() - - sys.stdout.write("shutting down... ") - sys.stdout.flush() - com.shutdown() - print("ok") diff --git a/python/test/Ice/acm/Client.py b/python/test/Ice/acm/Client.py deleted file mode 100755 index dee65d89d43..00000000000 --- a/python/test/Ice/acm/Client.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -from TestHelper import TestHelper - -TestHelper.loadSlice("Test.ice") -import AllTests - - -class Client(TestHelper): - def run(self, args): - properties = self.createTestProperties(args) - properties.setProperty("Ice.Warn.Connections", "0") - with self.initialize(properties=properties) as communicator: - AllTests.allTests(self, communicator) diff --git a/python/test/Ice/acm/Server.py b/python/test/Ice/acm/Server.py deleted file mode 100755 index d26ffe162b5..00000000000 --- a/python/test/Ice/acm/Server.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -import Ice -from TestHelper import TestHelper - -TestHelper.loadSlice("Test.ice") -import TestI - - -class Server(TestHelper): - def run(self, args): - properties = self.createTestProperties(args) - properties.setProperty("Ice.Warn.Connections", "0") - properties.setProperty("Ice.ACM.Timeout", "1") - with self.initialize(properties=properties) as communicator: - communicator.getProperties().setProperty( - "TestAdapter.Endpoints", self.getTestEndpoint() - ) - communicator.getProperties().setProperty("TestAdapter.ACM.Timeout", "0") - adapter = communicator.createObjectAdapter("TestAdapter") - adapter.add( - TestI.RemoteCommunicatorI(), Ice.stringToIdentity("communicator") - ) - adapter.activate() - - # Disable ready print for further adapters. - communicator.getProperties().setProperty("Ice.PrintAdapterReady", "0") - - communicator.waitForShutdown() diff --git a/python/test/Ice/acm/Test.ice b/python/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/python/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/python/test/Ice/acm/TestI.py b/python/test/Ice/acm/TestI.py deleted file mode 100644 index 6869492be42..00000000000 --- a/python/test/Ice/acm/TestI.py +++ /dev/null @@ -1,95 +0,0 @@ -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -import Ice -import Test -import threading - - -class ConnectionCallbackI: - def __init__(self): - self.m = threading.Condition() - self.count = 0 - - def heartbeat(self, con): - with self.m: - self.count += 1 - self.m.notifyAll() - - def waitForCount(self, count): - with self.m: - while self.count < count: - self.m.wait() - - -class RemoteCommunicatorI(Test.RemoteCommunicator): - def createObjectAdapter(self, timeout, close, heartbeat, current=None): - com = current.adapter.getCommunicator() - properties = com.getProperties() - protocol = properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp") - - name = Ice.generateUUID() - if timeout >= 0: - properties.setProperty(name + ".ACM.Timeout", str(timeout)) - if close >= 0: - properties.setProperty(name + ".ACM.Close", str(close)) - if heartbeat >= 0: - properties.setProperty(name + ".ACM.Heartbeat", str(heartbeat)) - properties.setProperty(name + ".ThreadPool.Size", "2") - adapter = com.createObjectAdapterWithEndpoints(name, protocol + " -h 127.0.0.1") - return Test.RemoteObjectAdapterPrx.uncheckedCast( - current.adapter.addWithUUID(RemoteObjectAdapterI(adapter)) - ) - - def shutdown(self, current=None): - current.adapter.getCommunicator().shutdown() - - -class RemoteObjectAdapterI(Test.RemoteObjectAdapter): - def __init__(self, adapter): - self._adapter = adapter - self._testIntf = Test.TestIntfPrx.uncheckedCast( - adapter.add(TestIntfI(), Ice.stringToIdentity("test")) - ) - adapter.activate() - - def getTestIntf(self, current=None): - return self._testIntf - - def activate(self, current=None): - self._adapter.activate() - - def hold(self, current=None): - self._adapter.hold() - - def deactivate(self, current=None): - try: - self._adapter.destroy() - except Ice.ObjectAdapterDeactivatedException: - pass - - -class TestIntfI(Test.TestIntf): - def __init__(self): - self.m = threading.Condition() - - def sleep(self, delay, current=None): - with self.m: - self.m.wait(delay) - - def sleepAndHold(self, delay, current=None): - with self.m: - current.adapter.hold() - self.m.wait(delay) - - def interruptSleep(self, delay, current=None): - with self.m: - self.m.notifyAll() - - def startHeartbeatCount(self, current=None): - self.callback = ConnectionCallbackI() - current.con.setHeartbeatCallback(lambda con: self.callback.heartbeat(con)) - - def waitForHeartbeatCount(self, count, current=None): - self.callback.waitForCount(2) diff --git a/ruby/ruby/IceLocal/Connection.rb b/ruby/ruby/IceLocal/Connection.rb index aeaac1e9c78..557a7381d1e 100644 --- a/ruby/ruby/IceLocal/Connection.rb +++ b/ruby/ruby/IceLocal/Connection.rb @@ -111,148 +111,6 @@ def initialize(underlying=nil, incoming=false, adapterName='', connectionId='') T_HeartbeatCallback = ::Ice::__declareLocalClass('::Ice::HeartbeatCallback') end - if not defined?(::Ice::ACMClose) - class ACMClose - include Comparable - - def initialize(name, value) - @name = name - @value = value - end - - def ACMClose.from_int(val) - @@_enumerators[val] - end - - def to_s - @name - end - - def to_i - @value - end - - def <=>(other) - other.is_a?(ACMClose) or raise ArgumentError, "value must be a ACMClose" - @value <=> other.to_i - end - - def hash - @value.hash - end - - def ACMClose.each(&block) - @@_enumerators.each_value(&block) - end - - CloseOff = ACMClose.new("CloseOff", 0) - CloseOnIdle = ACMClose.new("CloseOnIdle", 1) - CloseOnInvocation = ACMClose.new("CloseOnInvocation", 2) - CloseOnInvocationAndIdle = ACMClose.new("CloseOnInvocationAndIdle", 3) - CloseOnIdleForceful = ACMClose.new("CloseOnIdleForceful", 4) - - @@_enumerators = {0=>CloseOff, 1=>CloseOnIdle, 2=>CloseOnInvocation, 3=>CloseOnInvocationAndIdle, 4=>CloseOnIdleForceful} - - def ACMClose._enumerators - @@_enumerators - end - - private_class_method :new - end - - T_ACMClose = ::Ice::__defineEnum('::Ice::ACMClose', ACMClose, ACMClose::_enumerators) - end - - if not defined?(::Ice::ACMHeartbeat) - class ACMHeartbeat - include Comparable - - def initialize(name, value) - @name = name - @value = value - end - - def ACMHeartbeat.from_int(val) - @@_enumerators[val] - end - - def to_s - @name - end - - def to_i - @value - end - - def <=>(other) - other.is_a?(ACMHeartbeat) or raise ArgumentError, "value must be a ACMHeartbeat" - @value <=> other.to_i - end - - def hash - @value.hash - end - - def ACMHeartbeat.each(&block) - @@_enumerators.each_value(&block) - end - - HeartbeatOff = ACMHeartbeat.new("HeartbeatOff", 0) - HeartbeatOnDispatch = ACMHeartbeat.new("HeartbeatOnDispatch", 1) - HeartbeatOnIdle = ACMHeartbeat.new("HeartbeatOnIdle", 2) - HeartbeatAlways = ACMHeartbeat.new("HeartbeatAlways", 3) - - @@_enumerators = {0=>HeartbeatOff, 1=>HeartbeatOnDispatch, 2=>HeartbeatOnIdle, 3=>HeartbeatAlways} - - def ACMHeartbeat._enumerators - @@_enumerators - end - - private_class_method :new - end - - T_ACMHeartbeat = ::Ice::__defineEnum('::Ice::ACMHeartbeat', ACMHeartbeat, ACMHeartbeat::_enumerators) - end - - if not defined?(::Ice::ACM) - class ACM - include ::Ice::Inspect_mixin - def initialize(timeout=0, close=::Ice::ACMClose::CloseOff, heartbeat=::Ice::ACMHeartbeat::HeartbeatOff) - @timeout = timeout - @close = close - @heartbeat = heartbeat - end - - def hash - _h = 0 - _h = 5 * _h + @timeout.hash - _h = 5 * _h + @close.hash - _h = 5 * _h + @heartbeat.hash - _h % 0x7fffffff - end - - def ==(other) - return false if !other.is_a? ::Ice::ACM or - @timeout != other.timeout or - @close != other.close or - @heartbeat != other.heartbeat - true - end - - def eql?(other) - return other.class == self.class && other == self - end - - attr_accessor :timeout, :close, :heartbeat - end - - T_ACM = ::Ice::__defineStruct('::Ice::ACM', ACM, [ - ["timeout", ::Ice::T_int], - ["close", ::Ice::T_ACMClose], - ["heartbeat", ::Ice::T_ACMHeartbeat] - ]) - end - if not defined?(::Ice::ConnectionClose) class ConnectionClose include Comparable diff --git a/ruby/src/IceRuby/Connection.cpp b/ruby/src/IceRuby/Connection.cpp index 8f46debb9a9..69e506f5ecf 100644 --- a/ruby/src/IceRuby/Connection.cpp +++ b/ruby/src/IceRuby/Connection.cpp @@ -97,97 +97,6 @@ IceRuby_Connection_heartbeat(VALUE self) return Qnil; } -extern "C" VALUE -IceRuby_Connection_setACM(VALUE self, VALUE t, VALUE c, VALUE h) -{ - ICE_RUBY_TRY - { - Ice::ConnectionPtr* p = reinterpret_cast(DATA_PTR(self)); - assert(p); - - optional timeout; - optional close; - optional heartbeat; - - if (t != Unset) - { - timeout = static_cast(getInteger(t)); - } - - if (c != Unset) - { - volatile VALUE type = callRuby(rb_path2class, "Ice::ACMClose"); - if (callRuby(rb_obj_is_instance_of, c, type) != Qtrue) - { - throw RubyException( - rb_eTypeError, - "value for 'close' argument must be Unset or an enumerator of Ice.ACMClose"); - } - volatile VALUE closeValue = callRuby(rb_funcall, c, rb_intern("to_i"), 0); - assert(TYPE(closeValue) == T_FIXNUM); - close = static_cast(FIX2LONG(closeValue)); - } - - if (h != Unset) - { - volatile VALUE type = callRuby(rb_path2class, "Ice::ACMHeartbeat"); - if (callRuby(rb_obj_is_instance_of, h, type) != Qtrue) - { - throw RubyException( - rb_eTypeError, - "value for 'heartbeat' argument must be Unset or an enumerator of Ice.ACMHeartbeat"); - } - volatile VALUE heartbeatValue = callRuby(rb_funcall, h, rb_intern("to_i"), 0); - assert(TYPE(heartbeatValue) == T_FIXNUM); - heartbeat = static_cast(FIX2LONG(heartbeatValue)); - } - - try - { - (*p)->setACM(timeout, close, heartbeat); - } - catch (const invalid_argument& ex) - { - throw RubyException(rb_eArgError, ex.what()); - } - } - ICE_RUBY_CATCH - return Qnil; -} - -extern "C" VALUE -IceRuby_Connection_getACM(VALUE self) -{ - ICE_RUBY_TRY - { - Ice::ConnectionPtr* p = reinterpret_cast(DATA_PTR(self)); - assert(p); - - Ice::ACM acm = (*p)->getACM(); - volatile VALUE type = callRuby(rb_path2class, "Ice::ACM"); - assert(type != Qnil); - volatile VALUE r = callRuby(rb_class_new_instance, 0, static_cast(0), type); - assert(r != Qnil); - - callRuby(rb_ivar_set, r, rb_intern("@timeout"), LONG2FIX(acm.timeout)); - - type = callRuby(rb_path2class, "Ice::ACMClose"); - assert(type != Qnil); - volatile VALUE c = callRuby(rb_funcall, type, rb_intern("from_int"), 1, LONG2NUM(static_cast(acm.close))); - callRuby(rb_ivar_set, r, rb_intern("@close"), c); - - type = callRuby(rb_path2class, "Ice::ACMHeartbeat"); - assert(type != Qnil); - volatile VALUE h = - callRuby(rb_funcall, type, rb_intern("from_int"), 1, LONG2NUM(static_cast(acm.heartbeat))); - callRuby(rb_ivar_set, r, rb_intern("@heartbeat"), h); - - return r; - } - ICE_RUBY_CATCH - return Qnil; -} - extern "C" VALUE IceRuby_Connection_type(VALUE self) { @@ -420,8 +329,6 @@ IceRuby::initConnection(VALUE iceModule) rb_define_method(_connectionClass, "close", CAST_METHOD(IceRuby_Connection_close), 1); rb_define_method(_connectionClass, "flushBatchRequests", CAST_METHOD(IceRuby_Connection_flushBatchRequests), 1); rb_define_method(_connectionClass, "heartbeat", CAST_METHOD(IceRuby_Connection_heartbeat), 0); - rb_define_method(_connectionClass, "setACM", CAST_METHOD(IceRuby_Connection_setACM), 3); - rb_define_method(_connectionClass, "getACM", CAST_METHOD(IceRuby_Connection_getACM), 0); rb_define_method(_connectionClass, "type", CAST_METHOD(IceRuby_Connection_type), 0); rb_define_method(_connectionClass, "timeout", CAST_METHOD(IceRuby_Connection_timeout), 0); rb_define_method(_connectionClass, "getInfo", CAST_METHOD(IceRuby_Connection_getInfo), 0); diff --git a/ruby/test/Ice/acm/AllTests.rb b/ruby/test/Ice/acm/AllTests.rb deleted file mode 100644 index 99b4748bc47..00000000000 --- a/ruby/test/Ice/acm/AllTests.rb +++ /dev/null @@ -1,90 +0,0 @@ -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -def testSetACM(communicator, com) - print "testing setACM/getACM... " - STDOUT.flush - - adapter = com.createObjectAdapter(-1, -1, -1) - - initData = Ice::InitializationData.new - initData.properties = communicator.getProperties().clone() - initData.properties.setProperty("Ice.ACM.Timeout", "1") - initData.properties.setProperty("Ice.ACM.Client.Timeout", "15") - initData.properties.setProperty("Ice.ACM.Client.Close", "4") - initData.properties.setProperty("Ice.ACM.Client.Heartbeat", "2") - testCommunicator = Ice::initialize(initData) - proxy = Test::TestIntfPrx::uncheckedCast(testCommunicator.stringToProxy(adapter.getTestIntf().ice_toString())) - proxy.ice_getConnection() - - begin - proxy.ice_getCachedConnection().setACM(-19, Ice::Unset, Ice::Unset) - test(false) - rescue - end - - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 15) - test(acm.close == Ice::ACMClose::CloseOnIdleForceful) - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatOnIdle) - - proxy.ice_getCachedConnection().setACM(Ice::Unset, Ice::Unset, Ice::Unset) - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 15) - test(acm.close == Ice::ACMClose::CloseOnIdleForceful) - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatOnIdle) - - proxy.ice_getCachedConnection().setACM(1, Ice::ACMClose::CloseOnInvocationAndIdle, - Ice::ACMHeartbeat::HeartbeatAlways) - acm = proxy.ice_getCachedConnection().getACM() - test(acm.timeout == 1) - test(acm.close == Ice::ACMClose::CloseOnInvocationAndIdle) - test(acm.heartbeat == Ice::ACMHeartbeat::HeartbeatAlways) - - proxy.startHeartbeatCount() - proxy.waitForHeartbeatCount(2) - - adapter.deactivate() - testCommunicator.destroy() - puts "ok" -end - -def testHeartbeatManual(communicator, com) - print "testing manual heartbeats... " - STDOUT.flush - - adapter = com.createObjectAdapter(10, -1, 0) - - initData = Ice::InitializationData.new - initData.properties = communicator.getProperties().clone() - initData.properties.setProperty("Ice.ACM.Timeout", "10") - initData.properties.setProperty("Ice.ACM.Client.Timeout", "10") - initData.properties.setProperty("Ice.ACM.Client.Close", "0") - initData.properties.setProperty("Ice.ACM.Client.Heartbeat", "0") - testCommunicator = Ice::initialize(initData) - proxy = Test::TestIntfPrx::uncheckedCast(testCommunicator.stringToProxy(adapter.getTestIntf().ice_toString())) - con = proxy.ice_getConnection() - - proxy.startHeartbeatCount() - con.heartbeat() - con.heartbeat() - con.heartbeat() - con.heartbeat() - con.heartbeat() - proxy.waitForHeartbeatCount(5) - - adapter.deactivate() - testCommunicator.destroy() - puts "ok" -end - -def allTests(helper, communicator) - ref = "communicator:#{helper.getTestEndpoint()}" - com = Test::RemoteCommunicatorPrx::uncheckedCast(communicator.stringToProxy(ref)) - - testSetACM(communicator, com) - testHeartbeatManual(communicator, com) - - com.shutdown() -end diff --git a/ruby/test/Ice/acm/Client.rb b/ruby/test/Ice/acm/Client.rb deleted file mode 100755 index ad0dc08fc87..00000000000 --- a/ruby/test/Ice/acm/Client.rb +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby -# -# Copyright (c) ZeroC, Inc. All rights reserved. -# - -require "Ice" -Ice::loadSlice("Test.ice") -require './AllTests' - -class Client < ::TestHelper - def run(args) - properties = self.createTestProperties(args:args) - properties.setProperty("Ice.Warn.Connections", "0") - self.init(properties:properties) do |communicator| - allTests(self, communicator) - end - end -end diff --git a/ruby/test/Ice/acm/Test.ice b/ruby/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/ruby/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/scripts/tests/Glacier2/application.py b/scripts/tests/Glacier2/application.py index 7f27d0e2a9c..51db914848a 100644 --- a/scripts/tests/Glacier2/application.py +++ b/scripts/tests/Glacier2/application.py @@ -6,4 +6,4 @@ from Glacier2Util import Glacier2TestSuite -Glacier2TestSuite(__name__, routerProps={"Glacier2.SessionTimeout": 30}) +Glacier2TestSuite(__name__, routerProps={"Glacier2.Client.Connection.IdleTimeout": 30}) diff --git a/scripts/tests/Glacier2/router.py b/scripts/tests/Glacier2/router.py index 6026bb6a5b9..90ecd5e7995 100644 --- a/scripts/tests/Glacier2/router.py +++ b/scripts/tests/Glacier2/router.py @@ -21,7 +21,7 @@ "Ice.Warn.Connections": "0", "Glacier2.Filter.Category.Accept": "c1 c2", "Glacier2.Filter.Category.AcceptUser": "2", - "Glacier2.Client.ACM.Timeout": "30", + "Glacier2.Client.Connection.IdleTimeout": "30", } traceProps = { diff --git a/scripts/tests/Glacier2/sessionHelper.py b/scripts/tests/Glacier2/sessionHelper.py index 4ab17306ed1..51db914848a 100644 --- a/scripts/tests/Glacier2/sessionHelper.py +++ b/scripts/tests/Glacier2/sessionHelper.py @@ -6,4 +6,4 @@ from Glacier2Util import Glacier2TestSuite -Glacier2TestSuite(__name__, routerProps={"Glacier2.Client.ACM.Timeout": 30}) +Glacier2TestSuite(__name__, routerProps={"Glacier2.Client.Connection.IdleTimeout": 30}) diff --git a/slice/Glacier2/Router.ice b/slice/Glacier2/Router.ice index 45d8b51a0ec..2d480db2c0c 100644 --- a/slice/Glacier2/Router.ice +++ b/slice/Glacier2/Router.ice @@ -87,14 +87,12 @@ module Glacier2 void destroySession() throws SessionNotExistException; - /// Get the value of the session timeout. Sessions are destroyed if they see no activity for this period of - /// time. - /// @return The timeout (in seconds). + /// Get the idle timeout used by the server-side of the connection. + /// @return The idle timeout (in seconds). ["cpp:const"] idempotent long getSessionTimeout(); - /// Get the value of the ACM timeout. Clients supporting connection heartbeats can enable them instead of - /// explicitly sending keep alives requests. This method is only available since Ice 3.6. - /// @return The timeout (in seconds). + /// Get the idle timeout used by the server-side of the connection. + /// @return The idle timeout (in seconds). ["cpp:const"] idempotent int getACMTimeout(); } } diff --git a/slice/IceGrid/Registry.ice b/slice/IceGrid/Registry.ice index 45afbcc8de3..c422345ff0a 100644 --- a/slice/IceGrid/Registry.ice +++ b/slice/IceGrid/Registry.ice @@ -110,16 +110,12 @@ module IceGrid AdminSession* createAdminSessionFromSecureConnection() throws PermissionDeniedException; - /// Get the session timeout. If a client or administrative client doesn't call the session keepAlive method in - /// the time interval defined by this timeout, IceGrid might reap the session. - /// @see Session#keepAlive - /// @see AdminSession#keepAlive - /// @return The timeout (in seconds). + /// Get the idle timeout used by IceGrid for its side of the connection. + /// @return The idle timeout (in seconds). ["cpp:const"] idempotent int getSessionTimeout(); - /// Get the value of the ACM timeout. Clients supporting ACM connection heartbeats can enable them instead of - /// explicitly sending keep alives requests. This method is only available since Ice 3.6. - /// @return The timeout (in seconds). + /// Get the idle timeout used by IceGrid for its side of the connection. + /// @return The idle timeout (in seconds). ["cpp:const"] idempotent int getACMTimeout(); } diff --git a/swift/Rakefile b/swift/Rakefile index b81125490d5..e06c194e211 100644 --- a/swift/Rakefile +++ b/swift/Rakefile @@ -19,7 +19,6 @@ $macOSDeploymentTarget = "11" $iOSDeploymentTarget = "12.0" $tests = [ - "Ice/acm", "Ice/adapterDeactivation", "Ice/admin", "Ice/ami", diff --git a/swift/src/Ice/Connection.swift b/swift/src/Ice/Connection.swift index da3b050d09f..c39f7e9c291 100644 --- a/swift/src/Ice/Connection.swift +++ b/swift/src/Ice/Connection.swift @@ -77,155 +77,6 @@ extension OutputStream { } } -/// Specifies the close semantics for Active Connection Management. -public enum ACMClose: Swift.UInt8 { - /// CloseOff Disables automatic connection closure. - case CloseOff = 0 - /// CloseOnIdle Gracefully closes a connection that has been idle for the configured timeout period. - case CloseOnIdle = 1 - /// CloseOnInvocation Forcefully closes a connection that has been idle for the configured timeout period, but - /// only if the connection has pending invocations. - case CloseOnInvocation = 2 - /// CloseOnInvocationAndIdle Combines the behaviors of CloseOnIdle and CloseOnInvocation. - case CloseOnInvocationAndIdle = 3 - /// CloseOnIdleForceful Forcefully closes a connection that has been idle for the configured timeout period, - /// regardless of whether the connection has pending invocations or dispatch. - case CloseOnIdleForceful = 4 - public init() { - self = .CloseOff - } -} - -/// An `Ice.InputStream` extension to read `ACMClose` enumerated values from the stream. -extension InputStream { - /// Read an enumerated value. - /// - /// - returns: `ACMClose` - The enumarated value. - public func read() throws -> ACMClose { - let rawValue: Swift.UInt8 = try read(enumMaxValue: 4) - guard let val = ACMClose(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") - } - return val - } - - /// Read an optional enumerated value from the stream. - /// - /// - parameter tag: `Int32` - The numeric tag associated with the value. - /// - /// - returns: `ACMClose` - The enumerated value. - public func read(tag: Swift.Int32) throws -> ACMClose? { - guard try readOptional(tag: tag, expectedFormat: .Size) else { - return nil - } - return try read() as ACMClose - } -} - -/// An `Ice.OutputStream` extension to write `ACMClose` enumerated values to the stream. -extension OutputStream { - /// Writes an enumerated value to the stream. - /// - /// parameter _: `ACMClose` - The enumerator to write. - public func write(_ v: ACMClose) { - write(enum: v.rawValue, maxValue: 4) - } - - /// Writes an optional enumerated value to the stream. - /// - /// parameter tag: `Int32` - The numeric tag associated with the value. - /// - /// parameter _: `ACMClose` - The enumerator to write. - public func write(tag: Swift.Int32, value: ACMClose?) { - guard let v = value else { - return - } - write(tag: tag, val: v.rawValue, maxValue: 4) - } -} - -/// Specifies the heartbeat semantics for Active Connection Management. -public enum ACMHeartbeat: Swift.UInt8 { - /// HeartbeatOff Disables heartbeats. - case HeartbeatOff = 0 - /// HeartbeatOnDispatch Send a heartbeat at regular intervals if the connection is idle and only if there are - /// pending dispatch. - case HeartbeatOnDispatch = 1 - /// HeartbeatOnIdle Send a heartbeat at regular intervals when the connection is idle. - case HeartbeatOnIdle = 2 - /// HeartbeatAlways Send a heartbeat at regular intervals until the connection is closed. - case HeartbeatAlways = 3 - public init() { - self = .HeartbeatOff - } -} - -/// An `Ice.InputStream` extension to read `ACMHeartbeat` enumerated values from the stream. -extension InputStream { - /// Read an enumerated value. - /// - /// - returns: `ACMHeartbeat` - The enumarated value. - public func read() throws -> ACMHeartbeat { - let rawValue: Swift.UInt8 = try read(enumMaxValue: 3) - guard let val = ACMHeartbeat(rawValue: rawValue) else { - throw MarshalException(reason: "invalid enum value") - } - return val - } - - /// Read an optional enumerated value from the stream. - /// - /// - parameter tag: `Int32` - The numeric tag associated with the value. - /// - /// - returns: `ACMHeartbeat` - The enumerated value. - public func read(tag: Swift.Int32) throws -> ACMHeartbeat? { - guard try readOptional(tag: tag, expectedFormat: .Size) else { - return nil - } - return try read() as ACMHeartbeat - } -} - -/// An `Ice.OutputStream` extension to write `ACMHeartbeat` enumerated values to the stream. -extension OutputStream { - /// Writes an enumerated value to the stream. - /// - /// parameter _: `ACMHeartbeat` - The enumerator to write. - public func write(_ v: ACMHeartbeat) { - write(enum: v.rawValue, maxValue: 3) - } - - /// Writes an optional enumerated value to the stream. - /// - /// parameter tag: `Int32` - The numeric tag associated with the value. - /// - /// parameter _: `ACMHeartbeat` - The enumerator to write. - public func write(tag: Swift.Int32, value: ACMHeartbeat?) { - guard let v = value else { - return - } - write(tag: tag, val: v.rawValue, maxValue: 3) - } -} - -/// A collection of Active Connection Management configuration settings. -public struct ACM: Swift.Hashable { - /// A timeout value in seconds. - public var timeout: Swift.Int32 = 0 - /// The close semantics. - public var close: ACMClose = .CloseOff - /// The heartbeat semantics. - public var heartbeat: ACMHeartbeat = .HeartbeatOff - - public init() {} - - public init(timeout: Swift.Int32, close: ACMClose, heartbeat: ACMHeartbeat) { - self.timeout = timeout - self.close = close - self.heartbeat = heartbeat - } -} - /// Determines the behavior when manually closing a connection. public enum ConnectionClose: Swift.UInt8 { /// Forcefully Close the connection immediately without sending a close connection protocol message to the peer @@ -419,20 +270,6 @@ public protocol Connection: Swift.AnyObject, Swift.CustomStringConvertible { sent: ((Swift.Bool) -> Swift.Void)? ) -> PromiseKit.Promise - /// Set the active connection management parameters. - /// - /// - parameter timeout: `Swift.Int32?` The timeout value in seconds, must be >= 0. - /// - /// - parameter close: `ACMClose?` The close condition - /// - /// - parameter heartbeat: `ACMHeartbeat?` The hertbeat condition - func setACM(timeout: Swift.Int32?, close: ACMClose?, heartbeat: ACMHeartbeat?) - - /// Get the ACM parameters. - /// - /// - returns: `ACM` - The ACM parameters. - func getACM() -> ACM - /// Return the connection type. This corresponds to the endpoint type, i.e., "tcp", "udp", etc. /// /// - returns: `Swift.String` - The type of the connection. diff --git a/swift/src/Ice/ConnectionI.swift b/swift/src/Ice/ConnectionI.swift index 4f4e8ef57b8..4ed4016f5e7 100644 --- a/swift/src/Ice/ConnectionI.swift +++ b/swift/src/Ice/ConnectionI.swift @@ -122,24 +122,6 @@ class ConnectionI: LocalObject, Connection { } } - func setACM(timeout: Int32?, close: ACMClose?, heartbeat: ACMHeartbeat?) { - precondition(timeout ?? 0 >= 0, "Invalid negative ACM timeout value") - handle.setACM( - timeout as NSNumber?, - close: close != nil ? close.unsafelyUnwrapped.rawValue as NSNumber : nil, - heartbeat: heartbeat != nil ? heartbeat.unsafelyUnwrapped.rawValue as NSNumber : nil) - } - - func getACM() -> ACM { - var timeout = Int32() - var close = UInt8() - var heartbeat = UInt8() - handle.getACM(&timeout, close: &close, heartbeat: &heartbeat) - return ACM( - timeout: timeout, close: ACMClose(rawValue: close)!, - heartbeat: ACMHeartbeat(rawValue: heartbeat)!) - } - func type() -> String { return handle.type() } diff --git a/swift/src/IceImpl/Connection.h b/swift/src/IceImpl/Connection.h index 92f81275b81..51616a3bd67 100644 --- a/swift/src/IceImpl/Connection.h +++ b/swift/src/IceImpl/Connection.h @@ -27,8 +27,6 @@ ICEIMPL_API @interface ICEConnection : ICELocalObject - (BOOL)heartbeat:(NSError* _Nullable* _Nullable)error; - (void)heartbeatAsync:(void (^)(NSError*))exception sent:(void (^_Nullable)(bool))sent NS_SWIFT_NAME(heartbeatAsync(exception:sent:)); -- (void)setACM:(NSNumber* _Nullable)timeout close:(NSNumber* _Nullable)close heartbeat:(NSNumber* _Nullable)heartbeat; -- (void)getACM:(int32_t*)timeout close:(uint8_t*)close heartbeat:(uint8_t*)heartbeat; - (NSString*)type; - (int32_t)timeout; - (NSString*)toString; diff --git a/swift/src/IceImpl/Connection.mm b/swift/src/IceImpl/Connection.mm index 22744d2e583..42faee48855 100644 --- a/swift/src/IceImpl/Connection.mm +++ b/swift/src/IceImpl/Connection.mm @@ -202,38 +202,6 @@ - (void)heartbeatAsync:(void (^)(NSError*))exception sent:(void (^_Nullable)(boo } } -- (void)setACM:(NSNumber* _Nullable)timeout close:(NSNumber* _Nullable)close heartbeat:(NSNumber* _Nullable)heartbeat -{ - std::optional opTimeout; - std::optional opClose; - std::optional opHeartbeat; - - if (timeout != nil) - { - opTimeout = [timeout intValue]; - } - - if (close != nil) - { - opClose = Ice::ACMClose([close unsignedCharValue]); - } - - if (heartbeat != nil) - { - opHeartbeat = Ice::ACMHeartbeat([heartbeat unsignedCharValue]); - } - - self.connection->setACM(opTimeout, opClose, opHeartbeat); -} - -- (void)getACM:(int32_t*)timeout close:(std::uint8_t*)close heartbeat:(std::uint8_t*)heartbeat -{ - auto acm = self.connection->getACM(); - *timeout = acm.timeout; - *close = static_cast(acm.close); - *heartbeat = static_cast(acm.heartbeat); -} - - (NSString*)type { return toNSString(self.connection->type()); diff --git a/swift/test/Ice/acm/AllTests.swift b/swift/test/Ice/acm/AllTests.swift deleted file mode 100644 index 969adfa0247..00000000000 --- a/swift/test/Ice/acm/AllTests.swift +++ /dev/null @@ -1,586 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -import Foundation -import Ice -import PromiseKit -import TestCommon - -class LoggerI: Ice.Logger { - var _name: String - var _output: TextWriter - var _started: Bool - var _messages: [String] - var _dateFormat: DateFormatter - var _timeFormat: DateFormatter - var _lock = os_unfair_lock() - - init(name: String, output: TextWriter) { - _name = name - _output = output - _started = false - _messages = [String]() - - _dateFormat = DateFormatter() - _dateFormat.setLocalizedDateFormatFromTemplate("d") - - _timeFormat = DateFormatter() - _timeFormat.setLocalizedDateFormatFromTemplate("HH:mm:ss:fff") - } - - func start() { - withLock(&_lock) { - _started = true - dump() - } - } - - func print(_ msg: String) { - withLock(&_lock) { - _messages.append(msg) - if _started { - dump() - } - } - } - - func trace(category: String, message: String) { - withLock(&_lock) { - var s = _name - s += " " - s += _dateFormat.string(from: Date()) - s += " " - s += _timeFormat.string(from: Date()) - s += " " - s += "[" - s += category - s += "] " - s += message - _messages.append(s) - if _started { - dump() - } - } - } - - func warning(_ message: String) { - withLock(&_lock) { - var s = _name - s += " " - s += _dateFormat.string(from: Date()) - s += " " - s += _timeFormat.string(from: Date()) - s += " warning : " - s += message - _messages.append(s) - if _started { - dump() - } - } - } - - func error(_ message: String) { - withLock(&_lock) { - var s = _name - s += " " - s += _dateFormat.string(from: Date()) - s += " " - s += _timeFormat.string(from: Date()) - s += " error : " - s += message - _messages.append(s) - if _started { - dump() - } - } - } - - func getPrefix() -> String { - return "" - } - - func cloneWithPrefix(_: String) -> Ice.Logger { - return self - } - - func dump() { - for line in _messages { - _output.writeLine(line) - } - _messages = [] - } -} - -class TestCase { - var _name: String - var _com: RemoteCommunicatorPrx - var _msg: String! - var _output: TextWriter - var _logger: LoggerI - var _helper: TestHelper - - var _clientACMTimeout: Int32 - var _clientACMClose: Int32 - var _clientACMHeartbeat: Int32 - - var _serverACMTimeout: Int32 - var _serverACMClose: Int32 - var _serverACMHeartbeat: Int32 - - var _heartbeat: Int32 - var _closed: Bool - var _semaphore: DispatchSemaphore - var _lock = os_unfair_lock() - var _adapter: RemoteObjectAdapterPrx! - var _communicator: Ice.Communicator! - - var _queue: DispatchQueue - var _group: DispatchGroup - - init(name: String, com: RemoteCommunicatorPrx, helper: TestHelper) { - _name = name - _com = com - _output = helper.getWriter() - _logger = LoggerI(name: _name, output: _output) - _helper = helper - - _clientACMTimeout = -1 - _clientACMClose = -1 - _clientACMHeartbeat = -1 - - _serverACMTimeout = -1 - _serverACMClose = -1 - _serverACMHeartbeat = -1 - - _heartbeat = 0 - _closed = false - _semaphore = DispatchSemaphore(value: 0) - - _queue = DispatchQueue(label: name, qos: .background) - _group = DispatchGroup() - } - - func initialize() throws { - _adapter = try _com.createObjectAdapter( - acmTimeout: _serverACMTimeout, - close: _serverACMClose, - heartbeat: _serverACMHeartbeat) - - let properties = _com.ice_getCommunicator().getProperties().clone() - properties.setProperty(key: "Ice.ACM.Timeout", value: "2") - if _clientACMTimeout >= 0 { - properties.setProperty(key: "Ice.ACM.Client.Timeout", value: "\(_clientACMTimeout)") - } - - if _clientACMClose >= 0 { - properties.setProperty(key: "Ice.ACM.Client.Close", value: "\(_clientACMClose)") - } - - if _clientACMHeartbeat >= 0 { - properties.setProperty(key: "Ice.ACM.Client.Heartbeat", value: "\(_clientACMHeartbeat)") - } - // try properties.setProperty(key: "Ice.Trace.Protocol", value: "2") - // try properties.setProperty(key: "Ice.Trace.Network", value: "2") - - var initData = Ice.InitializationData() - initData.properties = properties - initData.logger = _logger - _communicator = try _helper.initialize(initData) - } - - func start() { - _group.enter() - _queue.async { - self.run() - self._group.leave() - } - } - - func destroy() throws { - try _adapter.deactivate() - _communicator.destroy() - } - - func join() throws { - _output.write("testing \(_name)... ") - _logger.start() - _group.wait() - if let msg = _msg { - _output.writeLine("failed! \(msg)") - throw Ice.RuntimeError(msg) - } else { - _output.writeLine("ok") - } - } - - func run() { - do { - let str = try _adapter.getTestIntf()!.ice_toString() - let proxy = try uncheckedCast( - prx: _communicator.stringToProxy(str)!, - type: TestIntfPrx.self) - try proxy.ice_getConnection()!.setCloseCallback { _ in - withLock(&self._lock) { - self._closed = true - self._semaphore.signal() - } - } - - try proxy.ice_getConnection()!.setHeartbeatCallback { _ in - withLock(&self._lock) { - self._heartbeat += 1 - } - } - - try runTestCase(adapter: _adapter, proxy: proxy) - } catch let e { - _msg = "unexpected exception:\n\(e)" - } - } - - func waitForClosed() { - do { - os_unfair_lock_lock(&_lock) - defer { - os_unfair_lock_unlock(&_lock) - } - - if _closed { - return - } - } - - if _semaphore.wait(timeout: .now() + Double(30)) == .timedOut { - preconditionFailure() // Waited for more than 30s for close, something's wrong. - } - precondition(_closed) - } - - func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - preconditionFailure("Abstract Method") - } - - func setClientACM(timeout: Int32, close: Int32, heartbeat: Int32) { - _clientACMTimeout = timeout - _clientACMClose = close - _clientACMHeartbeat = heartbeat - } - - func setServerACM(timeout: Int32, close: Int32, heartbeat: Int32) { - _serverACMTimeout = timeout - _serverACMClose = close - _serverACMHeartbeat = heartbeat - } -} - -class InvocationHeartbeatTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "invocation heartbeat", com: com, helper: helper) - // Faster ACM to make sure we receive enough ACM hearbeats - setServerACM(timeout: 1, close: -1, heartbeat: -1) - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - try proxy.sleep(4) - - try withLock(&_lock) { - try _helper.test(self._heartbeat >= 4) - } - } -} - -class InvocationHeartbeatOnHoldTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "invocation with heartbeat on hold", com: com, helper: helper) - // Use default ACM configuration. - } - - override func runTestCase(adapter: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - do { - // When the OA is put on hold, connections shouldn't - // send heartbeats, the invocation should therefore - // fail. - try proxy.sleepAndHold(10) - try _helper.test(false) - } catch is Ice.ConnectionTimeoutException { - try adapter.activate() - try proxy.interruptSleep() - waitForClosed() - } - } -} - -class InvocationNoHeartbeatTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "invocation with no heartbeat", com: com, helper: helper) - setServerACM(timeout: 2, close: 2, heartbeat: 0) // Disable heartbeat on invocations - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - do { - // Heartbeats are disabled on the server, the - // invocation should fail since heartbeats are - // expected. - try proxy.sleep(10) - try _helper.test(false) - } catch is Ice.ConnectionTimeoutException { - try proxy.interruptSleep() - waitForClosed() - try withLock(&_lock) { - try _helper.test(_heartbeat == 0) - } - } - } -} - -class InvocationHeartbeatCloseOnIdleTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "invocation with no heartbeat and close on idle", com: com, helper: helper) - setClientACM(timeout: 1, close: 1, heartbeat: 0) // Only close on idle. - setServerACM(timeout: 1, close: 2, heartbeat: 0) // Disable heartbeat on invocations - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - // No close on invocation, the call should succeed this - // time. - try proxy.sleep(3) - try withLock(&_lock) { - try _helper.test(self._heartbeat == 0) - try _helper.test(!self._closed) - } - } -} - -class CloseOnIdleTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "close on idle", com: com, helper: helper) - setClientACM(timeout: 1, close: 1, heartbeat: 0) // Only close on idle - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - waitForClosed() - try withLock(&_lock) { - try _helper.test(self._heartbeat == 0) - } - } -} - -class CloseOnInvocationTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "close on invocation", com: com, helper: helper) - setClientACM(timeout: 1, close: 2, heartbeat: 0) // Only close on invocation - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - Thread.sleep(forTimeInterval: 3) // Idle for 3 seconds - try withLock(&_lock) { - try _helper.test(self._heartbeat == 0) - try _helper.test(!self._closed) - } - } -} - -class CloseOnIdleAndInvocationTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "close on idle and invocation", com: com, helper: helper) - setClientACM(timeout: 3, close: 3, heartbeat: 0) // Only close on idle and invocation - } - - override func runTestCase(adapter: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - // - // Put the adapter on hold. The server will not respond to - // the graceful close. This allows to test whether or not - // the close is graceful or forceful. - // - try adapter.hold() - Thread.sleep(forTimeInterval: 5) // Idle for 5 seconds - - try withLock(&_lock) { - try _helper.test(self._heartbeat == 0) - try _helper.test(!self._closed) // Not closed yet because of graceful close. - } - - try adapter.activate() - waitForClosed() - } -} - -class ForcefulCloseOnIdleAndInvocationTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "forceful close on idle and invocation", com: com, helper: helper) - setClientACM(timeout: 1, close: 4, heartbeat: 0) // Only close on idle and invocation - } - - override func runTestCase(adapter: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - try adapter.hold() - waitForClosed() - try withLock(&_lock) { - try _helper.test(self._heartbeat == 0) - } - } -} - -class HeartbeatOnIdleTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "heartbeat on idle", com: com, helper: helper) - setServerACM(timeout: 1, close: -1, heartbeat: 2) // Enable server heartbeats. - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy _: TestIntfPrx) throws { - Thread.sleep(forTimeInterval: 3) - try withLock(&_lock) { - try _helper.test(_heartbeat >= 3) - } - } -} - -class HeartbeatAlwaysTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "heartbeat always", com: com, helper: helper) - setServerACM(timeout: 1, close: -1, heartbeat: 3) // Enable server heartbeats. - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - for _ in 0..<10 { - try proxy.ice_ping() - Thread.sleep(forTimeInterval: 0.3) - } - - try withLock(&_lock) { - try _helper.test(self._heartbeat >= 3) - } - } -} - -class HeartbeatManualTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "manual heartbeats", com: com, helper: helper) - // - // Disable heartbeats. - // - setClientACM(timeout: 10, close: -1, heartbeat: 0) - setServerACM(timeout: 10, close: -1, heartbeat: 0) - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - try proxy.startHeartbeatCount() - let con = try proxy.ice_getConnection()! - try con.heartbeat() - try con.heartbeat() - try con.heartbeat() - try con.heartbeat() - try con.heartbeat() - try proxy.waitForHeartbeatCount(5) - } -} - -class SetACMTest: TestCase { - init(com: RemoteCommunicatorPrx, helper: TestHelper) { - super.init(name: "setACM/getACM", com: com, helper: helper) - setClientACM(timeout: 15, close: 4, heartbeat: 0) - } - - override func runTestCase(adapter _: RemoteObjectAdapterPrx, proxy: TestIntfPrx) throws { - guard let con = proxy.ice_getCachedConnection() else { - fatalError() - } - - var acm = con.getACM() - try _helper.test(acm.timeout == 15) - try _helper.test(acm.close == .CloseOnIdleForceful) - try _helper.test(acm.heartbeat == .HeartbeatOff) - - con.setACM(timeout: nil, close: nil, heartbeat: nil) - acm = con.getACM() - try _helper.test(acm.timeout == 15) - try _helper.test(acm.close == .CloseOnIdleForceful) - try _helper.test(acm.heartbeat == .HeartbeatOff) - - con.setACM(timeout: 1, close: .CloseOnInvocationAndIdle, heartbeat: .HeartbeatAlways) - acm = con.getACM() - try _helper.test(acm.timeout == 1) - try _helper.test(acm.close == .CloseOnInvocationAndIdle) - try _helper.test(acm.heartbeat == .HeartbeatAlways) - - try proxy.startHeartbeatCount() - try proxy.waitForHeartbeatCount(2) - - let p1 = Promise { seal in - do { - try con.setCloseCallback { _ in - seal.fulfill(()) - } - } catch { - seal.reject(error) - } - } - try con.close(.Gracefully) - try p1.wait() - - do { - try con.throwException() - try _helper.test(false) - } catch is Ice.ConnectionManuallyClosedException {} - - try Promise { seal in - do { - try con.setCloseCallback { _ in - seal.fulfill(()) - } - } catch { - seal.reject(error) - } - }.wait() - - con.setHeartbeatCallback { _ in - preconditionFailure() - } - } -} - -func allTests(helper: TestHelper) throws { - let writer = helper.getWriter() - let communicator = helper.communicator() - - let com = try uncheckedCast( - prx: communicator.stringToProxy("communicator:\(helper.getTestEndpoint(num: 0))")!, - type: RemoteCommunicatorPrx.self) - - let tests: [TestCase] = [ - InvocationHeartbeatTest(com: com, helper: helper), - InvocationHeartbeatOnHoldTest(com: com, helper: helper), - InvocationNoHeartbeatTest(com: com, helper: helper), - InvocationHeartbeatCloseOnIdleTest(com: com, helper: helper), - - CloseOnIdleTest(com: com, helper: helper), - CloseOnInvocationTest(com: com, helper: helper), - CloseOnIdleAndInvocationTest(com: com, helper: helper), - ForcefulCloseOnIdleAndInvocationTest(com: com, helper: helper), - - HeartbeatOnIdleTest(com: com, helper: helper), - HeartbeatAlwaysTest(com: com, helper: helper), - HeartbeatManualTest(com: com, helper: helper), - SetACMTest(com: com, helper: helper), - ] - - for t in tests { - try t.initialize() - } - - for t in tests { - t.start() - } - - for t in tests { - try t.join() - } - - for t in tests { - try t.destroy() - } - - writer.write("shutting down... ") - try com.shutdown() - writer.writeLine("ok") -} diff --git a/swift/test/Ice/acm/Client.swift b/swift/test/Ice/acm/Client.swift deleted file mode 100644 index 13a2866fcf7..00000000000 --- a/swift/test/Ice/acm/Client.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -import Ice -import PromiseKit -import TestCommon - -class Client: TestHelperI { - override func run(args: [String]) throws { - let properties = try createTestProperties(args) - properties.setProperty(key: "Ice.Warn.Connections", value: "0") - - let communicator = try initialize(properties) - defer { - communicator.destroy() - } - try allTests(helper: self) - } -} diff --git a/swift/test/Ice/acm/Server.swift b/swift/test/Ice/acm/Server.swift deleted file mode 100644 index 15c744655e2..00000000000 --- a/swift/test/Ice/acm/Server.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -import Ice -import PromiseKit -import TestCommon - -class Server: TestHelperI { - override public func run(args: [String]) throws { - let properties = try createTestProperties(args) - properties.setProperty(key: "Ice.Warn.Connections", value: "0") - properties.setProperty(key: "Ice.ACM.Timeout", value: "1") - - let communicator = try initialize(properties) - defer { - communicator.destroy() - } - communicator.getProperties().setProperty( - key: "TestAdapter.Endpoints", value: getTestEndpoint(num: 0)) - communicator.getProperties().setProperty(key: "TestAdapter.ACM.Timeout", value: "0") - let adapter = try communicator.createObjectAdapter("TestAdapter") - try adapter.add( - servant: RemoteCommunicatorDisp(RemoteCommunicatorI()), - id: Ice.stringToIdentity("communicator")) - try adapter.activate() - serverReady() - communicator.getProperties().setProperty(key: "Ice.PrintAdapterReady", value: "0") - communicator.waitForShutdown() - } -} diff --git a/swift/test/Ice/acm/Test.ice b/swift/test/Ice/acm/Test.ice deleted file mode 100644 index 94bafde6dbf..00000000000 --- a/swift/test/Ice/acm/Test.ice +++ /dev/null @@ -1,33 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -#pragma once - -module Test -{ - -interface TestIntf -{ - void sleep(int seconds); - void sleepAndHold(int seconds); - void interruptSleep(); - void startHeartbeatCount(); - void waitForHeartbeatCount(int count); -} - -interface RemoteObjectAdapter -{ - TestIntf* getTestIntf(); - void activate(); - void hold(); - void deactivate(); -} - -interface RemoteCommunicator -{ - RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); - void shutdown(); -} - -} diff --git a/swift/test/Ice/acm/TestI.swift b/swift/test/Ice/acm/TestI.swift deleted file mode 100644 index 22a6b8406c6..00000000000 --- a/swift/test/Ice/acm/TestI.swift +++ /dev/null @@ -1,116 +0,0 @@ -// -// Copyright (c) ZeroC, Inc. All rights reserved. -// - -import Foundation -import Ice - -class RemoteCommunicatorI: RemoteCommunicator { - func createObjectAdapter( - acmTimeout: Int32, - close: Int32, - heartbeat: Int32, - current: Ice.Current - ) throws -> RemoteObjectAdapterPrx? { - let communicator = current.adapter!.getCommunicator() - let properties = communicator.getProperties() - let defaultProtocol = properties.getPropertyWithDefault( - key: "Ice.Default.Protocol", value: "tcp") - let defaultHost = properties.getPropertyWithDefault(key: "Ice.Default.Host", value: "127.0.0.1") - - let name = UUID().uuidString - if acmTimeout >= 0 { - properties.setProperty(key: "\(name).ACM.Timeout", value: "\(acmTimeout)") - } - - if close >= 0 { - properties.setProperty(key: "\(name).ACM.Close", value: "\(close)") - } - - if heartbeat >= 0 { - properties.setProperty(key: "\(name).ACM.Heartbeat", value: "\(heartbeat)") - } - properties.setProperty(key: "\(name).ThreadPool.Size", value: "2") - - let adapter = try communicator.createObjectAdapterWithEndpoints( - name: name, - endpoints: "\(defaultProtocol) -h \"\(defaultHost)\"" - ) - - return try uncheckedCast( - prx: current.adapter!.addWithUUID( - RemoteObjectAdapterDisp(RemoteObjectAdapterI(adapter: adapter))), - type: RemoteObjectAdapterPrx.self - ) - } - - func shutdown(current: Ice.Current) throws { - current.adapter!.getCommunicator().shutdown() - } -} - -class RemoteObjectAdapterI: RemoteObjectAdapter { - var _adapter: Ice.ObjectAdapter - var _testIntf: TestIntfPrx - - init(adapter: Ice.ObjectAdapter) throws { - _adapter = adapter - _testIntf = try uncheckedCast( - prx: adapter.add( - servant: TestIntfDisp(TestI()), - id: Ice.stringToIdentity("test")), - type: TestIntfPrx.self) - try _adapter.activate() - } - - func getTestIntf(current _: Current) -> TestIntfPrx? { - return _testIntf - } - - func activate(current _: Current) throws { - try _adapter.activate() - } - - func hold(current _: Current) { - _adapter.hold() - } - - func deactivate(current _: Current) { - _adapter.destroy() - } -} - -class TestI: TestIntf { - let _semaphore: DispatchSemaphore - var _hearbeatCallback: DispatchSemaphore! - - public init() { - _semaphore = DispatchSemaphore(value: 0) - } - - func sleep(seconds: Int32, current _: Current) { - _ = _semaphore.wait(timeout: .now() + Double(seconds)) - } - - func sleepAndHold(seconds: Int32, current: Current) { - current.adapter!.hold() - _ = _semaphore.wait(timeout: .now() + Double(seconds)) - } - - func interruptSleep(current _: Current) { - _semaphore.signal() - } - - func startHeartbeatCount(current: Current) { - _hearbeatCallback = DispatchSemaphore(value: 0) - current.con?.setHeartbeatCallback { _ in - self._hearbeatCallback.signal() - } - } - - func waitForHeartbeatCount(count: Int32, current _: Current) { - for _ in 0..