void Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend) { string prefix = prepend ? paramPrefix : ""; for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { writeParamEndCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData()); } if(op && op->returnType()) { writeParamEndCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData()); } }
void Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, bool cpp11) { string prefix = prepend ? paramPrefix : ""; for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { writeParamAllocateCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData(), typeCtx, cpp11, getEndArg((*p)->type(),(*p)->getMetaData(), (*p)->name()) != (*p)->name()); } if(op && op->returnType()) { writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData(), typeCtx, cpp11, getEndArg(op->returnType(), op->getMetaData(), "__ret") != "__ret"); } }
void Slice::ObjCGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p) { if(p->hasMetaData("UserException")) { ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); if(!cl->isLocal()) { ostringstream os; os << "ignoring invalid metadata `UserException': directive applies only to local operations " << ": warning: metadata directive `UserException' applies only to local operations " << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name() << "' is not local"; emitWarning(p->file(), p->line(), os.str()); } } validate(p); }
void SyncManagerImpl::OnSyncChangeReceived(const NetworkConnectionPtr& connection, NetworkInMessage& msg) { #if defined(SYNC_DEBUG) LogInfo("%s ReceivedSyncPacket", m_syncContext->GetLocalUser()->GetName().GetString().c_str()); #endif size_t connectionIndex; if (GetIndexOfConnection(connection, connectionIndex)) { RemoteSyncPeer& remotePeer = m_remoteHosts[connectionIndex]; if (XTVERIFY(remotePeer.m_bHandshakeComplete)) { XTASSERT(remotePeer.m_systemID != kUnknownSystemID); // Read out the number of ops sent in this message int32 numOps = msg.ReadInt32(); // Read out each of the ops for (int32 i = 0; i < numOps; ++i) { VersionedOp incomingVersionedOp; // Read the state that the remote machine was in before the op was applied incomingVersionedOp.m_state.m_opsSent = msg.ReadInt32(); incomingVersionedOp.m_state.m_opsReceived = msg.ReadInt32(); // Read the type of the op Operation::Type opType = (Operation::Type)msg.ReadByte(); // Create an op of the appropriate type OperationPtr incomingOp = m_syncContext->GetOpFactory().Make(opType, remotePeer.m_authorityLevel); // Read the op data incomingOp->Deserialize(msg); incomingVersionedOp.m_op = incomingOp; // Add it to the list of incoming ops remotePeer.m_incoming.push_back(incomingVersionedOp); } } } }
std::string Server::handleQuery(const std::string& query) { std::cout << "PARSING QUERY: " << query << std::endl; OperationPtr operation = parseQuery(query); if(operation.get() == NULL) return Linda::Messages::INVALID_MESSAGE; ParserToDatabaseProxy answerHandler(db); answerHandler.handleOperation(operation); if(answerHandler.shouldLastOperationWait()) { lastTimeout_ = answerHandler.getLastOperationTimeout(); return Linda::Messages::TIMEOUT_MESSAGE; } else if(answerHandler.hasLastOperationAddedElement()) handleWaitingQueue(); return answerHandler.getLastOperationAnswer(); }
string CodeGenerator::generateJSServerImp(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr) { ostringstream str; str << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype." << oPtr->getId() << " = function (current"; vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr(); for (size_t i = 0; i < vParamDecl.size(); i++) { str << ", " << vParamDecl[i]->getTypeIdPtr()->getId(); } str << ") {" << endl; INC_TAB; str << TAB << "//TODO::" << endl; DEL_TAB; str << "};" << endl << endl; return str.str(); }
string Slice::classDefToDelegateString(const ClassDefPtr& cl, int typeCtx, bool cpp11) { assert(cl->isDelegate()); // A delegate only has one operation OperationPtr op = cl->allOperations().front(); TypePtr ret = op->returnType(); string retS = returnTypeToString(ret, op->returnIsOptional(), op->getMetaData(), typeCtx, cpp11); string t = "::std::function<" + retS + " ("; if(cpp11) { // inputTypeToString usually passes local operation values by // reference. This is not the desired behavior for delegates typeCtx &= ~TypeContextLocalOperation; typeCtx |= TypeContextDelegate; } ParamDeclList paramList = cl->allOperations().front()->parameters(); for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q) { if((*q)->isOutParam()) { t += outputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx, cpp11); } else { t += inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx, cpp11); } t += distance(q, paramList.end()) == 1 ? "" : ", "; } t += ")>"; return t; }
string Slice::opFormatTypeToString(const OperationPtr& op) { switch(op->format()) { case DefaultFormat: return "::Ice::DefaultFormat"; case CompactFormat: return "::Ice::CompactFormat"; case SlicedFormat: return "::Ice::SlicedFormat"; default: assert(false); } return "???"; }
void SyncManagerImpl::Update() { PROFILE_SCOPE("SyncManager Update"); const OperationList& appliedOpList = m_syncContext->GetAppliedOperations(); // Add all the locally applied changes to the outgoing queue of the remote peers if (!appliedOpList.empty()) { for (size_t i = 0; i < appliedOpList.size(); ++i) { for (size_t j = 0; j < m_remoteHosts.size(); ++j) { RemoteSyncPeer& currentHost = m_remoteHosts[j]; if (currentHost.m_bHandshakeComplete && currentHost.m_bHasAddedStartingState) { currentHost.SendOp(appliedOpList[i]); } } } // Clear out the list of locally applied operations m_syncContext->ClearAppliedOperations(); } // Check to see if any new remote peers have connected since the last sync, and if so // add create operation for each element in our list to their outgoing queue for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex) { RemoteSyncPeer& currentHost = m_remoteHosts[hostIndex]; if (currentHost.m_bHandshakeComplete && !currentHost.m_bHasAddedStartingState) { #if defined(SYNC_DEBUG) LogInfo("%s Sending Deltas", m_syncContext->GetLocalUser()->GetName().GetString().c_str()); #endif // Check that the deltas are the first ops we are sending to the remote client XTASSERT(currentHost.m_localState.m_opsSent == 0); XTASSERT(currentHost.m_outgoing.empty()); XTASSERT(currentHost.m_sendList.empty()); AddCreateOpForElementRecurs(currentHost, m_syncContext->GetRootObject()); currentHost.m_bHasAddedStartingState = true; } } const TransformManager& transfromMgr = m_syncContext->GetTransformManager(); // Loop through all the incoming remote changes for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex) { RemoteSyncPeer& currentHost = m_remoteHosts[hostIndex]; if (currentHost.m_bHandshakeComplete) { VersionedOpList& incomingOpList = currentHost.m_incoming; VersionedOpList& outgoingOpList = currentHost.m_outgoing; // For each incoming operation for (VersionedOpList::iterator opIt = incomingOpList.begin(); opIt != incomingOpList.end(); ++opIt) { VersionedOp& remoteMsg = *opIt; // Debugging hack if (remoteMsg.m_state.m_opsSent == 0) { // The first op we get should be a catch-up data create of the root XTASSERT(remoteMsg.m_op->GetType() == Operation::Create && remoteMsg.m_op->GetTargetGuid() == m_syncContext->GetRootObject()->GetGUID()); } #if defined(SYNC_DEBUG) LogInfo("%s received op (%s) from %s, version %i %i", m_syncContext->GetLocalUser()->GetName().GetString().c_str(), remoteMsg.m_op->GetOpDescription().c_str(), currentHost.m_userName.c_str(), remoteMsg.m_state.m_opsSent, remoteMsg.m_state.m_opsReceived); #endif // Discard the acknowledged operations, we don't need to transform against them anymore while (!outgoingOpList.empty() && outgoingOpList.front().m_state.m_opsSent < remoteMsg.m_state.m_opsReceived) { #if defined(SYNC_DEBUG) LogInfo(" Invalidating %s op, version %i %i", outgoingOpList.front().m_op->GetTypeName(), outgoingOpList.front().m_state.m_opsSent, outgoingOpList.front().m_state.m_opsReceived); #endif outgoingOpList.erase(outgoingOpList.begin()); } if (remoteMsg.m_op->GetType() != Operation::Ack) { // Ensure that our starting state is the same as the one the message was sent from XTASSERT(remoteMsg.m_state.m_opsSent == currentHost.m_localState.m_opsReceived); // Transform the incoming ops by the changes that have not yet been acknowledged by the remote host for (VersionedOpList::iterator outgoingOpIt = outgoingOpList.begin(); outgoingOpIt != outgoingOpList.end(); ++outgoingOpIt) { VersionedOp& localMsg = *outgoingOpIt; TransformedPair transformResult = transfromMgr.Transform(localMsg.m_op, remoteMsg.m_op); localMsg.m_op = transformResult.m_localOpTransformed; remoteMsg.m_op = transformResult.m_remoteOpTransformed; // Early-out of the loop if the op was rendered invalid by the transformation if (remoteMsg.m_op->GetType() == Operation::Noop) { break; } } if (remoteMsg.m_op->GetType() != Operation::Noop) { // Const-cast so that we can apply the operation and change the auth level. // All the rest of the code uses const for safety, as the ops should not change except when applied OperationPtr clonedOp = const_cast<Operation*>(remoteMsg.m_op.get()); // Apply the transformed ops to the local data set clonedOp->Apply(m_syncContext); // Now that the op has been applied locally, it is set to the local system's authority level before // being queued to be passed to the other systems clonedOp->SetAuthorityLevel(m_syncContext->GetAuthorityLevel()); // Add the op to the list of changes applied this Sync so that we can notify the listeners when all changes have been applied m_pendingNotifications.push(clonedOp); // Add the transformed op to the outgoing list for the other hosts for (size_t otherHostIndex = 0; otherHostIndex < m_remoteHosts.size(); ++otherHostIndex) { if (otherHostIndex != hostIndex) { RemoteSyncPeer& otherHost = m_remoteHosts[otherHostIndex]; if (otherHost.m_bHandshakeComplete && otherHost.m_bHasAddedStartingState) { otherHost.SendOp(clonedOp); } } } } ++currentHost.m_localState.m_opsReceived; } // Record what we know of the state of the remote machine currentHost.m_remoteState = remoteMsg.m_state; } incomingOpList.clear(); } } // Send the changes in each remotePeer's outgoing op list. // Nothing will be sent if the last message was not acknowledged. for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex) { SendSyncMessage(m_remoteHosts[hostIndex]); } // Notify listeners about the remote changes if (!m_pendingNotifications.empty()) { if (m_listener) { try { m_listener->OnSyncChangesBegin(); } catch (...) { LogError("Exception occurred during OnSyncChangesBegin callback"); } } while (!m_pendingNotifications.empty()) { OperationPtr currentOp = m_pendingNotifications.front(); try { currentOp->Notify(m_syncContext); } catch (...) { LogError("Exception occurred during Sync notification callback"); } m_pendingNotifications.pop(); } if (m_listener) { try { m_listener->OnSyncChangesEnd(); } catch (...) { LogError("Exception occurred during OnSyncChangesEnd callback"); } } } }