void
PushService::merge( PushService* other, PacketContainerList& packetList,
                    vector<uint32>& lastUpdateTime )
{
   if ( other->getServiceID() == getServiceID() ) {
      // Merge resource IDs
      PushResourceDataMap::iterator it = other->m_resourceData.begin();
      
      while ( it != other->m_resourceData.end() ) {
         // Find resouceID
         PushResourceDataMap::iterator fit = m_resourceData.find( 
            it->first );
         if ( fit == m_resourceData.end() ) { // Not found
            packetList.push_back( makeSubscribePacket( 
               *it->first, it->second->getTimeForLastUpdate() ) );
            addResource( *it->first, it->second->getTimeForLastUpdate() );
            lastUpdateTime.push_back( it->second->getTimeForLastUpdate() );
         } else {
            lastUpdateTime.push_back( 
               fit->second->getTimeForLastUpdate() );
         }

         ++it;
      }
      
   } else {
      mc2log << warn << "PushService::merge serviceID missmatch! other "
             << other->getServiceID() << " != " << getServiceID() << endl;
   }
}
uint32 
PushService::checkAndCalculateTimeout( PacketContainerList& packetList ) {
   uint32 now = TimeUtility::getRealTime();
   PushResourceDataMap::iterator it = m_resourceData.begin();
   uint32 timeNextTimeOut = now + getResendSubscriptionTimeout() +
      getReceiveTimeout(); // Larger than all timeouts
   uint32 timeOutTime = 0;

   while ( it != m_resourceData.end() ) {
      if ( it->second->getPushSocket() != NULL ) { // Connected
         timeOutTime = it->second->getTimeForLastProviderContact() + 
            getReceiveTimeout();
         if ( timeOutTime <= now ) {
            mc2dbg2 << "PushService::checkAndCalculateTimeout "
                   << "Connected Resource time out, resubscribe serviceID "
                   << getServiceID() << " resource ";
#ifdef DEBUG_LEVEL_2
            *it->first << mc2log;
#endif
            mc2dbg2 << " lastUpdateTime " 
                   << it->second->getTimeForLastUpdate() << endl;
            // Timeout, resubscribe
            it->second->setPushSocket( NULL ); 
            packetList.push_back( makeSubscribePacket( 
               *it->first, it->second->getTimeForLastUpdate() ) );
            it->second->setTimeForLastSentSubscription( now );
            timeOutTime = it->second->getTimeForLastSentSubscription() + 
               getResendSubscriptionTimeout();
         }
      } else { // Subscribing
         timeOutTime = it->second->getTimeForLastSentSubscription() + 
            getResendSubscriptionTimeout();
         if ( timeOutTime <= now ) {
            mc2dbg2 << "PushService::checkAndCalculateTimeout "
                   << "Subscribing Resource time out, subscribe serviceID "
                   << getServiceID() << " resource ";
#ifdef DEBUG_LEVEL_2
            *it->first << mc2log;
#endif
            mc2dbg2 << " lastUpdateTime " 
                   << it->second->getTimeForLastUpdate() << endl;
            // (Re)send subscription
            it->second->setPushSocket( NULL ); 
            packetList.push_back( makeSubscribePacket( 
               *it->first, it->second->getTimeForLastUpdate() ) );
            it->second->setTimeForLastSentSubscription( now );
            timeOutTime = it->second->getTimeForLastSentSubscription() + 
               getResendSubscriptionTimeout();
         }
      }
      if ( timeOutTime < timeNextTimeOut ) {
         timeNextTimeOut = timeOutTime;
      }

      ++it;
   }

   return timeNextTimeOut;
}
Beispiel #3
0
bool Service::finishLoad()
{
    setStatus(SS_WORKING);
    if (!isShell())
    {
       if (true)
       {
           LoadServiceNotice notice;
           notice.shellServiceInfos.push_back(ServiceInfo(
               getServiceDockerID(),
               getServiceType(),
               getServiceID(),
               getServiceName(),
               getStatus(),
               getClientDockerID(),
               getClientSessionID()));
           Docker::getRef().broadcastToDockers(notice, false);
       }

        if (getServiceTrait(getServiceType()) == STrait_Multi)
        {
            RefreshServiceToMgrNotice refreshNotice;
            refreshNotice.shellServiceInfos.push_back(ServiceInfo(
                getServiceDockerID(),
                getServiceType(),
                getServiceID(),
                getServiceName(),
                getStatus(),
                getClientDockerID(),
                getClientSessionID()));

            for (auto sd : ServiceDepends)
            {
                if (getServiceTrait(sd.first) == STrait_Single )
                {
                    toService(sd.first, refreshNotice, nullptr);
                }
            }
        }

        LOGI(*this << "local service finish load. service=" << getServiceName() << ", id=" << getServiceID());
    }
    else
    {
        LOGI(*this << "remote service finish load. service=" << getServiceName() << ", id=" << getServiceID());
    }
    
    return true;
}
Beispiel #4
0
void Service::toService(ServiceType serviceType, ServiceID serviceID, const OutOfBand &oob,  const char * block, unsigned int len, ServiceCallback cb)
{
    Tracing trace;
    trace.routing.fromServiceType = getServiceType();
    trace.routing.fromServiceID = getServiceID();
    trace.routing.traceBackID = 0;
    trace.routing.traceID = 0;
    trace.routing.toServiceType = serviceType;
    trace.routing.toServiceID = serviceID;
    trace.oob = oob;
    if (cb)
    {
        trace.routing.traceID = makeCallback(cb);
    }
    if (trace.routing.toServiceType == STClient && trace.routing.toServiceID == InvalidServiceID)
    {
        if ((trace.oob.clientDockerID == InvalidDockerID && trace.oob.clientSessionID != InvalidSessionID) 
            || (trace.oob.clientDockerID != InvalidDockerID && trace.oob.clientSessionID == InvalidSessionID))
        {
            LOGE("toService STClient via session ID but param had some wrong. the condition is clientDockerID and clientSessionID need all valid. trace=" << trace);
            return;
        }
        if (trace.oob.clientDockerID == InvalidDockerID && trace.oob.clientAvatarID == InvalidAvatarID && getServiceType() != STAvatar)
        {
            LOGE("toService STClient but can not get the avatar ID. trace=" << trace << ", this service=" << getServiceType());
            return;
        }
        if (trace.oob.clientDockerID == InvalidDockerID && trace.oob.clientAvatarID == InvalidAvatarID && getServiceType() == STAvatar)
        {
            trace.routing.toServiceID = getServiceID();
        }
        if (trace.oob.clientDockerID == InvalidDockerID && trace.oob.clientAvatarID != InvalidAvatarID)
        {
            trace.routing.toServiceID = trace.oob.clientAvatarID;
        }
    }
    else if (::getServiceTrait(trace.routing.toServiceType) == STrait_Multi && trace.routing.toServiceID == InvalidServiceID)
    {
        LOGE("toService STrait_Multi but can not get the toServiceID. trace=" << trace << ", this service=" << getServiceType());
        return;
    }
    Docker::getRef().toService(trace, block, len, false);
}
Beispiel #5
0
void Service::toDocker(DockerID dockerID, const char * block, unsigned int len)
{
    OutOfBand oob;
    if (getServiceType() == STAvatar)
    {
        oob.clientDockerID = getClientDockerID();
        oob.clientSessionID = getClientSessionID();
        oob.clientAvatarID = getServiceID();
    }
    toDocker(dockerID, oob, block, len);
}
Beispiel #6
0
void Service::toService(ServiceType serviceType, const char * block, unsigned int len, ServiceCallback cb)
{
    OutOfBand oob;
    if (getServiceType() == STAvatar)
    {
        oob.clientDockerID = getClientDockerID();
        oob.clientSessionID = getClientSessionID();
        oob.clientAvatarID = getServiceID();
    }
    toService(serviceType, InvalidServiceID, oob, block, len, cb);
}
bool
PushService::handlePushPacket( PushPacket* pushPacket, 
                               TCPSocket* pushSocket,
                               PacketContainerList& packetList,
                               bool& isDataPacket,
                               SubscriptionResource*& resource )
{
   set<SubscriptionResourceNotice> subscribed;
   set<SubscriptionResourceNotice> unsubscribed;
   bool isHeartBeat = false;

   if ( getPushPacketMaps( pushPacket, subscribed, unsubscribed,
                           isHeartBeat ) ) 
   {
      uint32 now = TimeUtility::getRealTime();

      if ( !isHeartBeat && subscribed.begin() != subscribed.end() ) {
         isDataPacket = true;
         resource = (**subscribed.begin()).clone();
      }
      
      set<SubscriptionResourceNotice>::iterator it = subscribed.begin();
      while( it != subscribed.end() ) {
         PushResourceDataMap::iterator rit = m_resourceData.find( *it );
         if ( rit == m_resourceData.end() ) {
            // We don't want this resource to be subscribed
            mc2dbg2 << "PushService::handlePushPacket, unwanted service "
                   << "unsubscribe, serviceID "
                   << getServiceID() << " resource ";
#ifdef DEBUG_LEVEL_2
            **it << mc2log;
#endif
            mc2dbg2 << endl;
            packetList.push_back( makeUnSubscribePacket( **it ) );
         } else {
            // Else all ok subscribed resource found update times
            rit->second->setPushSocket( pushSocket );
            if ( isHeartBeat ) {
               rit->second->setTimeForLastHeartbeat( now );
            } else { // Data packet
               rit->second->setTimeForLastUpdate( now );
            }
         }
         ++it;
      }
      
   } else {
      mc2log << warn << "PushService::handlePushPacket getPushPacketMaps "
             << "falied, strange packet: " << endl;
      pushPacket->dump();
   }

   return true;
}
Beispiel #8
0
bool Service::finishUnload()
{
    setStatus(SS_DESTROY);
    if (!isShell())
    {
        if (getServiceTrait(getServiceType()) == STrait_Multi)
        {
            RefreshServiceToMgrNotice refreshNotice;
            refreshNotice.shellServiceInfos.push_back(ServiceInfo(
                getServiceDockerID(),
                getServiceType(),
                getServiceID(),
                getServiceName(),
                getStatus(),
                getClientDockerID(),
                getClientSessionID()));
            for (auto sd : ServiceDepends)
            {
                if (getServiceTrait(sd.first) == STrait_Single)
                {
                    toService(sd.first, refreshNotice, nullptr);
                }
            }
        }

        UnloadedServiceNotice notice(getServiceType(), getServiceID());
        Docker::getRef().broadcastToDockers(notice, true);
        LOGI(*this << "local service finish unload. service=" << getServiceName() << ", id=" << getServiceID());
    }
    else
    {
        LOGI(*this << "remote service finish unload. service=" << getServiceName() << ", id=" << getServiceID());
    }
    for (auto tID : _repeatTimers)
    {
        SessionManager::getRef().cancelTimer(tID);
    }
    _repeatTimers.clear();
    return true;
}
Beispiel #9
0
void Service::toDocker(DockerID dockerID, const OutOfBand & oob, const char * block, unsigned int len)
{
    Tracing trc;
    trc.routing.fromServiceType = getServiceType();
    trc.routing.fromServiceID = getServiceID();
    trc.routing.traceID = 0;
    trc.routing.traceBackID = 0;
    trc.routing.toServiceType = STClient;
    trc.routing.toServiceID = InvalidServiceID;
    trc.oob = oob;
    WriteStream ws(ForwardToDocker::getProtoID());
    ws << trc;
    ws.appendOriginalData(block, len);
    Docker::getRef().sendViaDockerID(dockerID, ws.getStream(), ws.getStreamLen());
}
Beispiel #10
0
void Service::backToService(const Tracing & trace, const char * block, unsigned int len, ServiceCallback cb)
{
    Tracing trc;
    trc.routing.fromServiceType = getServiceType();
    trc.routing.fromServiceID = getServiceID();
    trc.routing.traceID = 0;
    trc.routing.traceBackID = trace.routing.traceID;
    trc.routing.toServiceType = trace.routing.fromServiceType;
    trc.routing.toServiceID = trace.routing.fromServiceID;
    trc.oob = trace.oob;
    if (cb)
    {
        trc.routing.traceID = makeCallback(cb);
    }
    Docker::getRef().toService(trc, block, len, false);
}
Beispiel #11
0
void Service::directToRealClient(DockerID clientDockerID, SessionID clientSessionID, const char * block, unsigned int len)
{
    if (clientDockerID == ServerConfig::getRef().getDockerID())
    {
        Docker::getRef().sendViaSessionID(clientSessionID, block, len);
        return;
    }
    Tracing trc;
    trc.routing.fromServiceType = getServiceType();
    trc.routing.fromServiceID = getServiceID();
    trc.routing.traceID = 0;
    trc.routing.traceBackID = 0;
    trc.routing.toServiceType = STClient;
    trc.routing.toServiceID = InvalidServiceID;
    trc.oob.clientDockerID = clientDockerID;
    trc.oob.clientSessionID = clientSessionID;
    trc.oob.clientAvatarID = InvalidServiceID;
    Docker::getRef().forwardToRemoteService(trc, block, len);
}