ServiceInfoSPtr FailoverManagerStoreTest::CreateServiceInfo(wstring name, ServiceTypeSPtr const& serviceType) { wstring placementConstraints = L""; int scaleoutCount = 0; return make_shared<ServiceInfo>( ServiceDescription(name, 0, 0, 10, 3, 2, true, true, TimeSpan::FromSeconds(60.0), TimeSpan::MaxValue, TimeSpan::FromSeconds(300.0), serviceType->Type, vector<ServiceCorrelationDescription>(), placementConstraints, scaleoutCount, vector<ServiceLoadMetricDescription>(), 0, vector<byte>()), serviceType, FABRIC_INVALID_SEQUENCE_NUMBER, false); }
ServiceDescription ServiceManager::find(const ServiceFilter& svcFilter, int timeout) { if(_svcPub->waitForSubscribers(1, timeout) < 1) { // there is no other ServiceManager yet UM_LOG_INFO("Failed to find another ServiceManager"); return ServiceDescription(); } Message* findMsg = svcFilter.toMessage(); std::string reqId = UUID::getUUID(); findMsg->putMeta("um.rpc.type", "discover"); findMsg->putMeta("um.rpc.reqId", reqId.c_str()); findMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID()); // Thread::sleepMs(1000); if(_findRequests.find(reqId) != _findRequests.end()) UM_LOG_WARN("Find request %s already received", reqId.c_str()); _findRequests[reqId] = new Monitor(); _svcPub->send(findMsg); delete findMsg; RScopeLock lock(_mutex); _findRequests[reqId]->wait(_mutex, timeout); delete _findRequests[reqId]; _findRequests.erase(reqId); if (_findResponses.find(reqId) == _findResponses.end()) { UM_LOG_INFO("Failed to find %s", svcFilter.getServiceName().c_str()); return ServiceDescription(); } // TODO: Remove other replies as they come in! Message* foundMsg = _findResponses[reqId]; assert(foundMsg != NULL); ServiceDescription svcDesc(foundMsg); svcDesc._svcManager = this; _findResponses.erase(reqId); delete foundMsg; return svcDesc; }
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); } } } }