summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/ServerAdapterI.cpp
diff options
context:
space:
mode:
authorJoe George <joe@zeroc.com>2015-03-03 17:30:50 -0500
committerJoe George <joe@zeroc.com>2015-05-12 11:41:55 -0400
commitd35bb9f5c19e34aee31f83d445695a8186ef675e (patch)
treed5324eaf44f5f9776495537c51653f50a66a7237 /cpp/src/IceGrid/ServerAdapterI.cpp
downloadice-d35bb9f5c19e34aee31f83d445695a8186ef675e.tar.bz2
ice-d35bb9f5c19e34aee31f83d445695a8186ef675e.tar.xz
ice-d35bb9f5c19e34aee31f83d445695a8186ef675e.zip
Ice 3.4.2 Source Distributionv3.4.2
Diffstat (limited to 'cpp/src/IceGrid/ServerAdapterI.cpp')
-rw-r--r--cpp/src/IceGrid/ServerAdapterI.cpp264
1 files changed, 264 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/ServerAdapterI.cpp b/cpp/src/IceGrid/ServerAdapterI.cpp
new file mode 100644
index 00000000000..814a2f283e2
--- /dev/null
+++ b/cpp/src/IceGrid/ServerAdapterI.cpp
@@ -0,0 +1,264 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <IceGrid/ServerAdapterI.h>
+#include <IceGrid/ServerI.h>
+#include <IceGrid/TraceLevels.h>
+#include <IceGrid/NodeI.h>
+
+using namespace std;
+using namespace IceGrid;
+
+ServerAdapterI::ServerAdapterI(const NodeIPtr& node,
+ ServerI* server,
+ const string& serverName,
+ const AdapterPrx& proxy,
+ const string& id) :
+ _node(node),
+ _this(proxy),
+ _serverId(serverName),
+ _id(id),
+ _server(server)
+{
+}
+
+ServerAdapterI::~ServerAdapterI()
+{
+ assert(_activateCB.empty());
+}
+
+void
+ServerAdapterI::activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current& current)
+{
+ {
+ Lock sync(*this);
+ if(_proxy)
+ {
+ //
+ // Return the adapter direct proxy.
+ //
+ cb->ice_response(_proxy);
+ return;
+ }
+ else if(_activateCB.empty())
+ {
+ //
+ // Nothing else waits for this adapter so we must make sure that this
+ // adapter if still activatable.
+ //
+ if(!_server->isAdapterActivatable(_id))
+ {
+ cb->ice_response(0);
+ return;
+ }
+ }
+
+ if(_node->getTraceLevels()->adapter > 2)
+ {
+ Ice::Trace out(_node->getTraceLevels()->logger, _node->getTraceLevels()->adapterCat);
+ out << "waiting for activation of server `" + _serverId + "' adapter `" << _id << "'";
+ }
+
+ _activateCB.push_back(cb);
+ if(_activateCB.size() > 1)
+ {
+ return;
+ }
+ _activateAfterDeactivating = _server->getState() >= Deactivating && _server->getState() < Destroying;
+ }
+
+ //
+ // Try to start the server. Note that we start the server outside
+ // the synchronization block since start() can block and callback
+ // on this adapter (when the server is deactivating for example).
+ //
+ try
+ {
+ _server->start(ServerI::OnDemand);
+ return;
+ }
+ catch(const ServerStartException& ex)
+ {
+ activationFailed(ex.reason);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ //
+ // The server associated to this adapter doesn't exist anymore. Somehow the database is
+ // inconsistent if this happens. The best thing to do is to destroy the adapter.
+ //
+ destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ ostringstream os;
+ os << "unexpected exception: " << ex;
+ activationFailed(os.str());
+ }
+}
+
+Ice::ObjectPrx
+ServerAdapterI::getDirectProxy(const Ice::Current& current) const
+{
+ Lock sync(*this);
+
+ //
+ // Return the adapter direct proxy if it's set. Otherwise, throw. The caller can eventually
+ // activate the adapter if it's activatable.
+ //
+ if(_proxy)
+ {
+ return _proxy;
+ }
+ else
+ {
+ AdapterNotActiveException ex;
+ ex.activatable = _server->isAdapterActivatable(_id);
+ throw ex;
+ }
+}
+
+void
+ServerAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current&)
+{
+ Lock sync(*this);
+
+ //
+ // We don't allow to override an existing proxy by another non
+ // null proxy if the server is not inactive.
+ //
+ if(!_node->allowEndpointsOverride())
+ {
+ if(prx && _proxy)
+ {
+ if(_server->getState() == Active)
+ {
+ throw AdapterActiveException();
+ }
+ }
+ }
+
+ bool updated = _proxy != prx;
+ _proxy = prx;
+
+ //
+ // If the server is being deactivated and the activation callback
+ // was added during the deactivation, we don't send the response
+ // now. The server is going to be activated again and the adapter
+ // activated.
+ //
+ if(_server->getState() < Deactivating || _server->getState() >= Destroying || !_activateAfterDeactivating)
+ {
+ for(vector<AMD_Adapter_activatePtr>::const_iterator p = _activateCB.begin(); p != _activateCB.end(); ++p)
+ {
+ (*p)->ice_response(_proxy);
+ }
+ _activateCB.clear();
+ }
+
+ if(updated)
+ {
+ AdapterDynamicInfo info;
+ info.id = _id;
+ info.proxy = _proxy;
+ _node->observerUpdateAdapter(info);
+ }
+
+ if(_proxy)
+ {
+ _server->adapterActivated(_id);
+ }
+ else
+ {
+ _server->adapterDeactivated(_id);
+ }
+
+ if(_node->getTraceLevels()->adapter > 1)
+ {
+ Ice::Trace out(_node->getTraceLevels()->logger, _node->getTraceLevels()->adapterCat);
+ out << "server `" + _serverId + "' adapter `" << _id << "' " << (_proxy ? "activated" : "deactivated");
+ if(_proxy)
+ {
+ out << ": " << _node->getCommunicator()->proxyToString(_proxy);
+ }
+ }
+}
+
+void
+ServerAdapterI::destroy()
+{
+ activationFailed("adapter destroyed");
+ try
+ {
+ _node->getAdapter()->remove(_this->ice_getIdentity());
+ }
+ catch(const Ice::LocalException&)
+ {
+ // Ignore.
+ }
+}
+
+void
+ServerAdapterI::clear()
+{
+ Lock sync(*this);
+ _proxy = 0;
+ _activateAfterDeactivating = false;
+}
+
+void
+ServerAdapterI::activationFailed(const std::string& reason)
+{
+
+ //
+ // The server couldn't be activated, trace and return the current adapter proxy.
+ //
+ if(_node->getTraceLevels()->adapter > 1)
+ {
+ Ice::Trace out(_node->getTraceLevels()->logger, _node->getTraceLevels()->adapterCat);
+ out << "server `" + _serverId + "' adapter `" << _id << "' activation failed: " << reason;
+ }
+
+ Lock sync(*this);
+ for(vector<AMD_Adapter_activatePtr>::const_iterator p = _activateCB.begin(); p != _activateCB.end(); ++p)
+ {
+ (*p)->ice_response(0);
+ }
+ _activateCB.clear();
+}
+
+void
+ServerAdapterI::activationCompleted()
+{
+ Lock sync(*this);
+ if(!_proxy)
+ {
+ //
+ // The server activation completed, but the adapter hasn't been activated.
+ //
+ if(_node->getTraceLevels()->adapter > 1)
+ {
+ Ice::Trace out(_node->getTraceLevels()->logger, _node->getTraceLevels()->adapterCat);
+ out << "server `" + _serverId + "' adapter `" << _id << "' activation failed: server activation completed";
+ }
+ }
+
+ for(vector<AMD_Adapter_activatePtr>::const_iterator p = _activateCB.begin(); p != _activateCB.end(); ++p)
+ {
+ (*p)->ice_response(_proxy);
+ }
+ _activateCB.clear();
+}
+
+AdapterPrx
+ServerAdapterI::getProxy() const
+{
+ return _this;
+}