void ServiceManager::addService(Service* service, ServiceDescription& desc) { RScopeLock lock(_mutex); if (service == NULL) return; intptr_t svcPtr = (intptr_t)service; if (_svc.find(svcPtr) != _svc.end()) return; desc._channelName = service->getChannelName(); desc._svcName = service->getName(); assert(desc._channelName.length() > 0); _svc[svcPtr] = service; _localSvcDesc[svcPtr] = desc; // connect service to all nodes the manager is connected to std::set<Node>::iterator nodeIter; nodeIter = _nodes.begin(); while(nodeIter != _nodes.end()) { ((Node)*nodeIter).connect(service); nodeIter++; } // iterate continuous queries and notify other service managers about matches. std::map<std::string, ServiceFilter>::iterator filterIter = _remoteQueries.begin(); while(filterIter != _remoteQueries.end()) { if (filterIter->second.matches(desc)) { Message* foundMsg = desc.toMessage(); foundMsg->putMeta("um.rpc.filterId", filterIter->second._uuid); foundMsg->putMeta("um.rpc.type", "discovered"); foundMsg->putMeta("um.rpc.channel", desc.getChannelName()); foundMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); _svcPub->send(foundMsg); delete foundMsg; } filterIter++; } }
void ServiceManager::removeService(Service* service) { RScopeLock lock(_mutex); if (service == NULL) return; intptr_t svcPtr = (intptr_t)service; if (_svc.find(svcPtr) == _svc.end()) return; std::set<Node>::iterator nodeIter = _nodes.begin(); while(nodeIter != _nodes.end()) { ((Node)*nodeIter).disconnect(service); nodeIter++; } assert(_localSvcDesc.find(svcPtr)!= _localSvcDesc.end()); ServiceDescription desc = _localSvcDesc[svcPtr]; // iterate continuous queries and notify other service managers about removals. std::map<std::string, ServiceFilter>::iterator filterIter = _remoteQueries.begin(); while(filterIter != _remoteQueries.end()) { if (filterIter->second.matches(desc)) { Message* removeMsg = desc.toMessage(); removeMsg->putMeta("um.rpc.filterId", filterIter->second._uuid); removeMsg->putMeta("um.rpc.type", "vanished"); removeMsg->putMeta("um.rpc.channel", desc.getChannelName()); removeMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); _svcPub->send(removeMsg); delete removeMsg; } filterIter++; } _svc.erase(svcPtr); _localSvcDesc.erase(svcPtr); }
void ServiceManager::removeService(Service* service) { ScopeLock lock(&_mutex); if (service == NULL) return; intptr_t svcPtr = (intptr_t)service; if (_svc.find(svcPtr) == _svc.end()) return; std::set<Node*>::iterator nodeIter = _nodes.begin(); while(nodeIter != _nodes.end()) { (*nodeIter++)->disconnect(service); } assert(_localSvcDesc.find(svcPtr)!= _localSvcDesc.end()); ServiceDescription* desc = _localSvcDesc[svcPtr]; // iterate continuous queries and notify other service managers about removals. std::map<string, ServiceFilter*>::iterator filterIter = _remoteQueries.begin(); while(filterIter != _remoteQueries.end()) { if (filterIter->second->matches(desc)) { Message* removeMsg = desc->toMessage(); removeMsg->setMeta("filterId", filterIter->second->_uuid); removeMsg->setMeta("type", "serviceDiscRemoved"); removeMsg->setMeta("desc:channel", desc->getChannelName()); _svcPub->send(removeMsg); delete removeMsg; } filterIter++; } _svc.erase(svcPtr); _localSvcDesc.erase(svcPtr); }
void ServiceManager::receive(Message* msg) { RScopeLock lock(_mutex); // is this a response for one of our requests? if (msg->getMeta().find("um.rpc.respId") != msg->getMeta().end()) { std::string respId = msg->getMeta("um.rpc.respId"); if (_findRequests.find(respId) != _findRequests.end()) { // put message into responses and signal waiting thread _findResponses[respId] = new Message(*msg); _findRequests[respId]->signal(); } } // is someone simply asking for a service via find? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("discover") == 0) { ServiceFilter filter(msg); std::set<ServiceDescription> foundSvcs = findLocal(filter); if (foundSvcs.size() > 0) { ServiceDescription svcDesc = (*(foundSvcs.begin())); Message* foundMsg = svcDesc.toMessage(); foundMsg->setReceiver(msg->getMeta("um.rpc.mgrId")); foundMsg->putMeta("um.rpc.respId", msg->getMeta("um.rpc.reqId")); foundMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); // if (_svcPub->isPublishingTo(msg->getMeta("um.rpc.mgrId"))) { _svcPub->send(foundMsg); // } else { // // queue message and send in welcome // _pendingMessages[msg->getMeta("um.rpc.mgrId")].push_back(std::make_pair(Thread::getTimeStampMs(), foundMsg)); // } delete foundMsg; } } // is this the start of a continuous query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("startDiscovery") == 0) { ServiceFilter filter(msg); _remoteQueries[filter.getUUID()] = filter; UM_LOG_INFO("Received query for '%s'", filter._svcName.c_str()); // do we have such a service? std::set<ServiceDescription> foundSvcs = findLocal(filter); std::set<ServiceDescription>::iterator svcDescIter = foundSvcs.begin(); while(svcDescIter != foundSvcs.end()) { Message* foundMsg = svcDescIter->toMessage(); foundMsg->setReceiver(msg->getMeta("um.rpc.mgrId")); foundMsg->putMeta("um.rpc.filterId", filter.getUUID()); foundMsg->putMeta("um.rpc.type", "discovered"); foundMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); _svcPub->send(foundMsg); delete foundMsg; svcDescIter++; } } // is this the end of a continuous query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && msg->getMeta("um.rpc.type").compare("stopDiscovery") == 0) { ServiceFilter filter(msg); if (_remoteQueries.find(filter.getUUID()) != _remoteQueries.end()) { _remoteQueries.erase(filter.getUUID()); } } // is this a reply to a continuous service query? if (msg->getMeta().find("um.rpc.type") != msg->getMeta().end() && (msg->getMeta("um.rpc.type").compare("discovered") == 0 || msg->getMeta("um.rpc.type").compare("vanished") == 0)) { // _svcQueries comparator uses filter uuid ServiceFilter keyFilter(""); keyFilter._uuid = msg->getMeta("um.rpc.filterId"); if (_localQueries.find(keyFilter) != _localQueries.end()) { ResultSet<ServiceDescription>* listener = _localQueries[keyFilter]; assert(msg->getMeta("um.rpc.desc.channel").size() > 0); assert(msg->getMeta("um.rpc.mgrId").size() > 0); std::string svcChannel = msg->getMeta("um.rpc.desc.channel"); std::string managerId = msg->getMeta("um.rpc.mgrId"); if (_remoteSvcDesc.find(managerId) == _remoteSvcDesc.end() || _remoteSvcDesc[managerId].find(svcChannel) == _remoteSvcDesc[managerId].end()) { _remoteSvcDesc[managerId][svcChannel] = ServiceDescription(msg); _remoteSvcDesc[managerId][svcChannel]._svcManager = this; } assert(_remoteSvcDesc.find(managerId) != _remoteSvcDesc.end()); assert(_remoteSvcDesc[managerId].find(svcChannel) != _remoteSvcDesc[managerId].end()); if (msg->getMeta("um.rpc.type").compare("discovered") == 0) { listener->added(_remoteSvcDesc[managerId][svcChannel]); } else { listener->removed(_remoteSvcDesc[managerId][svcChannel]); _remoteSvcDesc[managerId].erase(svcChannel); } } } }
void ServiceManager::receive(Message* msg) { ScopeLock lock(&_mutex); // is this a response for one of our requests? if (msg->getMeta().find("respId") != msg->getMeta().end()) { string respId = msg->getMeta("respId"); if (_findRequests.find(respId) != _findRequests.end()) { _findResponses[respId] = new Message(*msg); _findRequests[respId].signal(); } } // is someone asking for a service? if (msg->getMeta().find("type") != msg->getMeta().end() && msg->getMeta("type").compare("serviceDisc") == 0) { ServiceFilter* filter = new ServiceFilter(msg); std::set<ServiceDescription*> foundSvcs = findLocal(filter); delete filter; if (foundSvcs.size() > 0) { ServiceDescription* svcDesc = (*(foundSvcs.begin())); Message* foundMsg = svcDesc->toMessage(); foundMsg->setMeta("respId", msg->getMeta("reqId")); foundMsg->setMeta("desc:channel", svcDesc->getChannelName()); _svcPub->send(foundMsg); delete foundMsg; } } // is this the start of a continuous query? if (msg->getMeta().find("type") != msg->getMeta().end() && msg->getMeta("type").compare("serviceDiscStart") == 0) { ServiceFilter* filter = new ServiceFilter(msg); _remoteQueries[filter->_uuid] = filter; // do we have such a service? std::set<ServiceDescription*> foundSvcs = findLocal(filter); std::set<ServiceDescription*>::iterator svcDescIter = foundSvcs.begin(); while(svcDescIter != foundSvcs.end()) { if (filter->matches(*svcDescIter)) { Message* foundMsg = (*svcDescIter)->toMessage(); foundMsg->setMeta("filterId", filter->_uuid); foundMsg->setMeta("type", "serviceDiscFound"); foundMsg->setMeta("desc:channel", (*svcDescIter)->getChannelName()); _svcPub->send(foundMsg); delete foundMsg; } svcDescIter++; } } // is this the end of a continuous query? if (msg->getMeta().find("type") != msg->getMeta().end() && msg->getMeta("type").compare("serviceDiscStop") == 0) { ServiceFilter* filter = new ServiceFilter(msg); if (_remoteQueries.find(filter->_uuid) != _remoteQueries.end()) { delete _remoteQueries[filter->_uuid]; _remoteQueries.erase(filter->_uuid); } delete filter; } // is this a reply to a continuous service query? if (msg->getMeta().find("type") != msg->getMeta().end() && (msg->getMeta("type").compare("serviceDiscFound") == 0 || msg->getMeta("type").compare("serviceDiscRemoved") == 0)) { // _svcQueries comparator uses filter uuid ServiceFilter* keyFilter = new ServiceFilter(""); keyFilter->_uuid = msg->getMeta("filterId"); if (_localQueries.find(keyFilter) != _localQueries.end()) { ResultSet<ServiceDescription>* listener = _localQueries[keyFilter]; assert(msg->getMeta("desc:channel").size() > 0); if (_remoteSvcDesc.find(msg->getMeta("desc:channel")) == _remoteSvcDesc.end()) _remoteSvcDesc[msg->getMeta("desc:channel")] = shared_ptr<ServiceDescription>(new ServiceDescription(msg)); if (msg->getMeta("type").compare("serviceDiscFound") == 0) { listener->added(_remoteSvcDesc[msg->getMeta("desc:channel")]); } else { listener->removed(_remoteSvcDesc[msg->getMeta("desc:channel")]); _remoteSvcDesc.erase(msg->getMeta("desc:channel")); } } delete keyFilter; } }