Example #1
0
void
TopicImpl::update(const SubscriberRecordSeq& records)
{
    IceUtil::Mutex::Lock sync(_subscribersMutex);

    // We do this with two scans. The first runs through the subscribers
    // that we have and removes those not in the init list. The second
    // runs through the init list and add the ones that don't
    // exist.

    {
        vector<SubscriberPtr>::iterator p = _subscribers.begin();
        while(p != _subscribers.end())
        {
            SubscriberRecordSeq::const_iterator q;
            for(q = records.begin(); q != records.end(); ++q)
            {
                if((*p)->id() == q->id)
                {
                    break;
                }
            }
            // The subscriber doesn't exist in the incoming subscriber
            // set so destroy it.
            if(q == records.end())
            {
                (*p)->destroy();
                p = _subscribers.erase(p);
            }
            else
            {
                // Otherwise reset the reaped status if necessary.
                (*p)->resetIfReaped();
                ++p;
            }
        }
    }

    for(SubscriberRecordSeq::const_iterator p = records.begin(); p != records.end(); ++p)
    {
        vector<SubscriberPtr>::iterator q;
        for(q = _subscribers.begin(); q != _subscribers.end(); ++q)
        {
            if((*q)->id() == p->id)
            {
                break;
            }
        }
        if(q == _subscribers.end())
        {
            SubscriberPtr subscriber = Subscriber::create(_instance, *p);
            _subscribers.push_back(subscriber);
        }
    }
}
Example #2
0
TopicImpl::TopicImpl(
    const InstancePtr& instance,
    const string& name,
    const Ice::Identity& id,
    const SubscriberRecordSeq& subscribers) :
    _instance(instance),
    _name(name),
    _id(id),
    _connectionPool(instance->connectionPool()),
    _destroyed(false)
{
    try
    {
        __setNoDelete(true);
        
        // TODO: If we want to improve the performance of the
        // non-replicated case we could allocate a null-topic impl here.
        _servant = new TopicI(this, instance);

        //
        // Create a servant per topic to receive event data. If the
        // category is empty then we are in backwards compatibility
        // mode. In this case the servant's identity is
        // category=<topicname>, name=publish, otherwise the name is
        // <instancename>/<topicname>.publish. The same applies to the
        // link proxy.
        //
        // Activate the object and save a reference to give to publishers.
        //
        Ice::Identity pubid;
        Ice::Identity linkid;
        if(id.category.empty())
        {
            pubid.category = _name;
            pubid.name = "publish";
            linkid.category = _name;
            linkid.name = "link";
        }
        else
        {
            pubid.category = id.category;
            pubid.name = _name + ".publish";
            linkid.category = id.category;
            linkid.name = _name + ".link";
        }

        _publisherPrx = _instance->publishAdapter()->add(new PublisherI(this, instance), pubid);
        _linkPrx = TopicLinkPrx::uncheckedCast(
            _instance->publishAdapter()->add(new TopicLinkI(this, instance), linkid));
        
        //
        // Re-establish subscribers.
        //
        for(SubscriberRecordSeq::const_iterator p = subscribers.begin(); p != subscribers.end(); ++p)
        {
            Ice::Identity id = p->obj->ice_getIdentity();
            TraceLevelsPtr traceLevels = _instance->traceLevels();
            if(traceLevels->topic > 0)
            {
                Ice::Trace out(traceLevels->logger, traceLevels->topicCat);
                out << _name << " recreate " << _instance->communicator()->identityToString(id);
                if(traceLevels->topic > 1)
                {
                    out << " endpoints: " << IceStormInternal::describeEndpoints(p->obj);
                }
            }

            try
            {
                //
                // Create the subscriber object add it to the set of
                // subscribers.
                //
                SubscriberPtr subscriber = Subscriber::create(_instance, *p);
                _subscribers.push_back(subscriber);
            }
            catch(const Ice::Exception& ex)
            {
                Ice::Warning out(traceLevels->logger);
                out << _name << " recreate " << _instance->communicator()->identityToString(id);
                if(traceLevels->topic > 1)
                {
                    out << " endpoints: " << IceStormInternal::describeEndpoints(p->obj);
                }
                out << " failed: " << ex;
            }
        }

        if(_instance->observer())
        {
            _observer.attach(_instance->observer()->getTopicObserver(_instance->serviceName(), _name, 0));
        }
    }
    catch(...)
    {
        shutdown();
        __setNoDelete(false);
        throw;
    }
    __setNoDelete(false);
}