diff options
Diffstat (limited to 'cpp/src/IceGrid/ServerAdapterI.cpp')
-rw-r--r-- | cpp/src/IceGrid/ServerAdapterI.cpp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/ServerAdapterI.cpp b/cpp/src/IceGrid/ServerAdapterI.cpp new file mode 100644 index 00000000000..e2e03268fc9 --- /dev/null +++ b/cpp/src/IceGrid/ServerAdapterI.cpp @@ -0,0 +1,213 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 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/ServerFactory.h> +#include <IceGrid/TraceLevels.h> +#include <IceGrid/WaitQueue.h> + +using namespace std; +using namespace IceGrid; + +namespace IceGrid +{ + +class WaitForAdapterActivation : public WaitItem +{ +public: + + WaitForAdapterActivation(const ServerAdapterPtr& adapter, + const TraceLevelsPtr traceLevels, + const AMD_Adapter_activatePtr& cb) : + WaitItem(adapter), + _adapter(adapter), + _traceLevels(traceLevels), + _cb(cb) + { + } + + virtual void execute() + { + try + { + _cb->ice_response(_adapter->getDirectProxy()); + } + catch(const AdapterNotActiveException&) + { + _cb->ice_response(0); + } + catch(const Ice::LocalException&) + { + _cb->ice_response(0); + } + } + + virtual void expired(bool destroyed) + { + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << _adapter->id << "' activation timed out"; + } + _cb->ice_response(0); + } + +private: + + const ServerAdapterPtr _adapter; + const TraceLevelsPtr _traceLevels; + const AMD_Adapter_activatePtr _cb; +}; + +} + +ServerAdapterI::ServerAdapterI(const ServerFactoryPtr& factory, const TraceLevelsPtr& traceLevels, + Ice::Int waitTime) : + _factory(factory), + _traceLevels(traceLevels), + _waitTime(IceUtil::Time::seconds(waitTime)) +{ +} + +ServerAdapterI::~ServerAdapterI() +{ +} + +string +ServerAdapterI::getId(const Ice::Current&) +{ + return id; +} + +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; + } + + if(_traceLevels->adapter > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "waiting for activation of server adapter `" << id << "'"; + } + + _factory->getWaitQueue()->add(new WaitForAdapterActivation(this, _traceLevels, cb), _waitTime); + } + + // + // 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 + { + if(svr->start(OnDemand)) + { + return; + } + } + 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 and throw + // an ObjectNotExist exception. + // + destroy(current); + } + + // + // The server couldn't be activated, trace and return the current adapter proxy. + // + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << id << "' activation failed, couldn't start the server"; + } + + _factory->getWaitQueue()->notifyAllWaitingOn(this); +} + +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; + ServerState state = svr->getState(); + ex.activatable = svr->getActivationMode() == OnDemand || state == Activating || state == Active; + ex.timeout = static_cast<int>(_waitTime.toMilliSeconds()); + throw ex; + } +} + +void +ServerAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current& current) +{ + Lock sync(*this); + + // + // If the adapter proxy is not null the given proxy can only be null. We don't allow to overide an + // existing proxy by another non null proxy if the server is active. + // + if(prx && _proxy) + { + if(svr->getState() == Active) + { + throw AdapterActiveException(); + } + } + + // + // Prevent eviction of an active adapter object. + // + if(prx && !_proxy) + { + _factory->getServerAdapterEvictor()->keep(current.id); + } + else if(!prx && _proxy) + { + _factory->getServerAdapterEvictor()->release(current.id); + } + + _proxy = prx; + + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << id << "' " << (_proxy ? "activated" : "deactivated"); + } + + _factory->getWaitQueue()->notifyAllWaitingOn(this); +} + +void +ServerAdapterI::destroy(const Ice::Current& current) +{ + _factory->destroy(this, current.id); +} |