void TransientTopicImpl::link(const TopicPrx& topic, Ice::Int cost, const Ice::Current&) { TopicInternalPrx internal = TopicInternalPrx::uncheckedCast(topic); TopicLinkPrx link = internal->getLinkProxy(); TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << ": link " << _instance->communicator()->identityToString(topic->ice_getIdentity()) << " cost " << cost; } Lock sync(*this); Ice::Identity id = topic->ice_getIdentity(); SubscriberRecord record; record.id = id; record.obj = link; record.theTopic = topic; record.topicName = _name; record.link = true; record.cost = cost; vector<SubscriberPtr>::iterator p = find(_subscribers.begin(), _subscribers.end(), record.id); if(p != _subscribers.end()) { throw LinkExists(IceStormInternal::identityToTopicName(id)); } SubscriberPtr subscriber = Subscriber::create(_instance, record); _subscribers.push_back(subscriber); }
void TransientTopicImpl::unlink(const TopicPrx& topic, const Ice::Current&) { Lock sync(*this); if(_destroyed) { throw Ice::ObjectNotExistException(__FILE__, __LINE__); } Ice::Identity id = topic->ice_getIdentity(); vector<SubscriberPtr>::iterator p = find(_subscribers.begin(), _subscribers.end(), id); if(p == _subscribers.end()) { string name = IceStormInternal::identityToTopicName(id); TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << ": unlink " << name << " failed - not linked"; } throw NoSuchLink(name); } TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << " unlink " << _instance->communicator()->identityToString(id); } // Remove the subscriber from the subscribers list. Note // that its possible that the subscriber isn't in the list, but is // in the database if the subscriber was locally reaped. p = find(_subscribers.begin(), _subscribers.end(), id); if(p != _subscribers.end()) { (*p)->destroy(); _subscribers.erase(p); } }
void TopicImpl::unlink(const TopicPrx& topic) { IceUtil::Mutex::Lock sync(_subscribersMutex); if(_destroyed) { throw Ice::ObjectNotExistException(__FILE__, __LINE__); } Ice::Identity id = topic->ice_getIdentity(); vector<SubscriberPtr>::const_iterator p = find(_subscribers.begin(), _subscribers.end(), id); if(p == _subscribers.end()) { string name = identityToTopicName(id); TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << ": unlink " << name << " failed - not linked"; } NoSuchLink ex; ex.name = name; throw ex; } TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << " unlink " << _instance->communicator()->identityToString(id); } Ice::IdentitySeq ids; ids.push_back(id); removeSubscribers(ids); }
void TopicImpl::link(const TopicPrx& topic, Ice::Int cost) { TopicInternalPrx internal = TopicInternalPrx::uncheckedCast(topic); TopicLinkPrx link = internal->getLinkProxy(); TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << ": link " << _instance->communicator()->identityToString(topic->ice_getIdentity()) << " cost " << cost; } IceUtil::Mutex::Lock sync(_subscribersMutex); Ice::Identity id = topic->ice_getIdentity(); SubscriberRecord record; record.id = id; record.obj = link; record.theTopic = topic; record.topicName = _name; record.link = true; record.cost = cost; vector<SubscriberPtr>::iterator p = find(_subscribers.begin(), _subscribers.end(), record.id); if(p != _subscribers.end()) { string name = identityToTopicName(id); LinkExists ex; ex.name = name; throw ex; } LogUpdate llu; SubscriberPtr subscriber = Subscriber::create(_instance, record); for(;;) { try { DatabaseConnectionPtr connection = _connectionPool->newConnection(); TransactionHolder txn(connection); SubscriberRecordKey key; key.topic = _id; key.id = id; SubscribersWrapperPtr subscribersWrapper = _connectionPool->getSubscribers(connection); subscribersWrapper->put(key, record); LLUWrapperPtr lluWrapper = _connectionPool->getLLU(connection); llu = lluWrapper->get(); llu.iteration++; lluWrapper->put(llu); txn.commit(); break; } catch(const DeadlockException&) { continue; } catch(const DatabaseException& ex) { halt(_instance->communicator(), ex); } } _subscribers.push_back(subscriber); _instance->observers()->addSubscriber(llu, _name, record); }
void TopicImpl::link(const TopicPrx& topic, Ice::Int cost) { TopicInternalPrx internal = TopicInternalPrx::uncheckedCast(topic); TopicLinkPrx link = internal->getLinkProxy(); TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->topic > 0) { Ice::Trace out(traceLevels->logger, traceLevels->topicCat); out << _name << ": link " << _instance->communicator()->identityToString(topic->ice_getIdentity()) << " cost " << cost; } IceUtil::Mutex::Lock sync(_subscribersMutex); Ice::Identity id = topic->ice_getIdentity(); SubscriberRecord record; record.id = id; record.obj = link; record.theTopic = topic; record.topicName = _name; record.link = true; record.cost = cost; vector<SubscriberPtr>::iterator p = find(_subscribers.begin(), _subscribers.end(), record.id); if(p != _subscribers.end()) { string name = IceStormInternal::identityToTopicName(id); LinkExists ex; ex.name = name; throw ex; } LogUpdate llu; SubscriberPtr subscriber = Subscriber::create(_instance, record); try { IceDB::ReadWriteTxn txn(_instance->dbEnv()); SubscriberRecordKey key; key.topic = _id; key.id = id; _subscriberMap.put(txn, key, record); llu = getIncrementedLLU(txn, _lluMap); txn.commit(); } catch(const IceDB::LMDBException& ex) { logError(_instance->communicator(), ex); throw; // will become UnknownException in caller } _subscribers.push_back(subscriber); _instance->observers()->addSubscriber(llu, _name, record); }