TopicManagerImpl::TopicManagerImpl(const InstancePtr& instance) :
    _instance(instance),
    _connectionPool(instance->connectionPool())
{
    try
    {
        __setNoDelete(true);

        if(_instance->observer())
        {
            _instance->observer()->setObserverUpdater(this);
        }

        // TODO: If we want to improve the performance of the
        // non-replicated case we could allocate a null-topic manager impl
        // here.
        _managerImpl = new TopicManagerI(instance, this);

        Ice::PropertiesPtr properties = _instance->communicator()->getProperties();
        // If there is no node adapter we don't need to start the
        // observer, nor sync since we're not replicating.
        if(_instance->nodeAdapter())
        {
            _observerImpl = new ReplicaObserverI(instance, this);
            _observer = _instance->nodeAdapter()->addWithUUID(_observerImpl);
            _syncImpl = new TopicManagerSyncI(this);
            _sync = _instance->nodeAdapter()->addWithUUID(_syncImpl);
        }

        DatabaseConnectionPtr connection = _connectionPool->newConnection();

        // Ensure that the llu counter is present in the log.
        LLUWrapperPtr lluWrapper = _connectionPool->getLLU(connection);
        LogUpdate empty = {0, 0};
        lluWrapper->put(empty);

        // Recreate each of the topics.
        SubscribersWrapperPtr subscribersWrapper = _connectionPool->getSubscribers(connection);
        map<SubscriberRecordKey, SubscriberRecord> subscriberMap = subscribersWrapper->getMap();

        map<SubscriberRecordKey, SubscriberRecord>::const_iterator p = subscriberMap.begin();
        while(p != subscriberMap.end())
        {
            // This record has to be a place holder record, otherwise
            // there is a database bug.
            assert(p->first.id.name.empty() && p->first.id.category.empty());

            Ice::Identity topic = p->first.topic;

            // Skip the place holder.
            ++p;
            
            SubscriberRecordSeq content;
            while(p != subscriberMap.end() && p->first.topic == topic)
            {
                content.push_back(p->second);
                ++p;
            }
            
            string name = identityToTopicName(topic);
            installTopic(name, topic, false, content);
        }
    }
    catch(...)
    {
        shutdown();
        __setNoDelete(false);
        throw;
    }
    __setNoDelete(false);
}
Exemple #2
0
TopicManagerImpl::TopicManagerImpl(const PersistentInstancePtr& instance) :
    _instance(instance),
    _lluMap(instance->lluMap()),
    _subscriberMap(instance->subscriberMap())
{
    try
    {
        __setNoDelete(true);

        if(_instance->observer())
        {
            _instance->observer()->setObserverUpdater(this);
        }

        // TODO: If we want to improve the performance of the
        // non-replicated case we could allocate a null-topic manager impl
        // here.
        _managerImpl = new TopicManagerI(instance, this);

        // If there is no node adapter we don't need to start the
        // observer, nor sync since we're not replicating.
        if(_instance->nodeAdapter())
        {
            _observerImpl = new ReplicaObserverI(instance, this);
            _observer = _instance->nodeAdapter()->addWithUUID(_observerImpl);
            _syncImpl = new TopicManagerSyncI(this);
            _sync = _instance->nodeAdapter()->addWithUUID(_syncImpl);
        }

        {
            IceDB::ReadWriteTxn txn(_instance->dbEnv());

            // Ensure that the llu counter is present in the log.
            LogUpdate empty = {0, 0};
            _instance->lluMap().put(txn, lluDbKey, empty);

            // Recreate each of the topics.
            SubscriberRecordKey k;
            SubscriberRecord v;

            SubscriberMapRWCursor cursor(_subscriberMap, txn);
            if(cursor.get(k, v, MDB_FIRST))
            {
                bool moreTopics = false;
                do
                {
                    // This record has to be a place holder record, otherwise
                    // there is a database bug.
                    assert(k.id.name.empty() && k.id.category.empty());

                    Ice::Identity topic = k.topic;

                    bool moreTopics;
                    SubscriberRecordSeq content;
                    while((moreTopics = cursor.get(k, v, MDB_NEXT)) && k.topic == topic)
                    {
                        content.push_back(v);
                    }

                    string name = identityToTopicName(topic);
                    installTopic(name, topic, false, content);
                } while(moreTopics);
            }

            txn.commit();
        }
    }
    catch(...)
    {
        shutdown();
        __setNoDelete(false);
        throw;
    }
    __setNoDelete(false);
}