virtual void process() { CMasterActivity::process(); bool results = false; unsigned nslaves = container.queryJob().querySlaves(); while (nslaves--) { CMessageBuffer mb; if (abortSoon || !receiveMsg(mb, RANK_ALL, replyTag, NULL)) break; StringBuffer str; mb.getSender().getUrlStr(str); size32_t sz; mb.read(sz); if (sz) { if (results) throw MakeThorException(TE_UnexpectedMultipleSlaveResults, "Received greater than one result from slaves"); IHThorRemoteResultArg *helper = (IHThorRemoteResultArg *)queryHelper(); Owned<IThorRowInterfaces> resultRowIf = createRowInterfaces(helper->queryOutputMeta()); CThorStreamDeserializerSource mds(sz, mb.readDirect(sz)); RtlDynamicRowBuilder rowBuilder(resultRowIf->queryRowAllocator()); size32_t sz = resultRowIf->queryRowDeserializer()->deserialize(rowBuilder, mds); OwnedConstThorRow result = rowBuilder.finalizeRowClear(sz); helper->sendResult(result); results = true; } } if (!results && !abortSoon) { ActPrintLog("WARNING: no results"); IHThorRemoteResultArg *helper = (IHThorRemoteResultArg *)queryHelper(); //helper->sendResult(NULL); // Jake I think this always cores (so raise exception instead) throw MakeThorException(TE_UnexpectedMultipleSlaveResults, "Received no results from slaves"); } }
void processMessage(CMessageBuffer &mb) { ICoven &coven=queryCoven(); SessionId id; int fn; mb.read(fn); switch (fn) { case MSR_REGISTER_PROCESS_SESSION: { acceptConnections.wait(); acceptConnections.signal(); Owned<INode> node(deserializeINode(mb)); Owned<INode> servernode(deserializeINode(mb)); // hopefully me, but not if forwarded int role=0; if (mb.length()-mb.getPos()>=sizeof(role)) { // a capability block present mb.read(role); if (!manager.authorizeConnection(role,false)) { SocketEndpoint sender = mb.getSender(); mb.clear(); coven.reply(mb); MilliSleep(100+getRandom()%1000); // Causes client to 'work' for a short time. Owned<INode> node = createINode(sender); coven.disconnect(node); break; } #ifdef _DEBUG StringBuffer eps; PROGLOG("Connection to %s authorized",mb.getSender().getUrlStr(eps).str()); #endif } IGroup *covengrp; id = manager.registerClientProcess(node.get(),covengrp,(DaliClientRole)role); mb.clear().append(id); if (covengrp->rank(servernode)==RANK_NULL) { // must have been redirected covengrp->Release(); // no good, so just use one we know about (may use something more sophisticated later) INode *na = servernode.get(); covengrp = createIGroup(1, &na); } covengrp->serialize(mb); covengrp->Release(); coven.reply(mb); } break; case MSR_SECONDARY_REGISTER_PROCESS_SESSION: { mb.read(id); Owned<INode> node (deserializeINode(mb)); int role; mb.read(role); manager.addProcessSession(id,node.get(),(DaliClientRole)role); mb.clear(); coven.reply(mb); } break; case MSR_REGISTER_SESSION: { SecurityToken tok; SessionId parentid; mb.read(tok).read(parentid); SessionId id = manager.registerSession(tok,parentid); mb.clear().append(id); coven.reply(mb); } break; case MSR_SECONDARY_REGISTER_SESSION: { mb.read(id); manager.addSession(id); mb.clear(); coven.reply(mb); } break; case MSR_LOOKUP_PROCESS_SESSION: { // looks up from node or from id Owned<INode> node (deserializeINode(mb)); if (node->endpoint().isNull()&&(mb.length()-mb.getPos()>=sizeof(id))) { mb.read(id); INode *n = manager.getProcessSessionNode(id); if (n) node.setown(n); node->serialize(mb.clear()); } else { id = manager.lookupProcessSession(node.get()); mb.clear().append(id); } coven.reply(mb); } break; case MSR_STOP_SESSION: { SessionId sessid; bool failed; mb.read(sessid).read(failed); manager.stopSession(sessid,failed); mb.clear(); coven.reply(mb); } break; case MSR_LOOKUP_LDAP_PERMISSIONS: { StringAttr key; StringAttr obj; Owned<IUserDescriptor> udesc=createUserDescriptor(); StringAttr username; StringAttr passwordenc; mb.read(key).read(obj); udesc->deserialize(mb); #ifndef _NO_DALIUSER_STACKTRACE //following debug code to be removed StringBuffer sb; udesc->getUserName(sb); if (0==sb.length()) { DBGLOG("UNEXPECTED USER (NULL) in dasess.cpp CSessionRequestServer::processMessage() line %d", __LINE__); } #endif unsigned auditflags = 0; if (mb.length()-mb.getPos()>=sizeof(auditflags)) mb.read(auditflags); int err = 0; int ret=manager.getPermissionsLDAP(key,obj,udesc,auditflags,&err); mb.clear().append(ret); if (err) mb.append(err); coven.reply(mb); } break; } }
bool SortSlaveMP::marshall(ISortSlaveMP &slave, ICommunicator* comm, mptag_t tag) { CMessageBuffer mb; rank_t sender; comm->recv(mb,0,tag,&sender); // NB only recv from master if (mb.length()==0) { PROGLOG("Stopping SortSlaveMP::marshall"); return false; } byte fn; mb.read(fn); CMessageBuffer mbout; mbout.init(mb.getSender(),tag,mb.getReplyTag()); byte okout=1; mbout.append(okout); #ifdef FULLTRACE StringBuffer tmp1; PROGLOG(">SortSlaveMP::marshall(%d) got %d from %s tag %d replytag %d",(int)fn, mb.length(), mb.getSender().getUrlStr(tmp1).str(),tag,mb.getReplyTag()); #endif bool replydone = false; Owned<IException> err; try { switch ((MPSlaveFunctions)(int)fn) { case FN_Connect: { unsigned _part; unsigned _numnodes; mb.read(_part).read(_numnodes); bool ret = slave.Connect(_part,_numnodes); mbout.append(ret); } break; case FN_StartGather: { slave.StartGather(); } break; case FN_GetGatherInfo: { bool hasserializer; mb.read(hasserializer); rowcount_t numlocal; unsigned overflowscale; offset_t totalsize; slave.GetGatherInfo(numlocal,totalsize,overflowscale,hasserializer); mbout.append(numlocal).append(totalsize).append(overflowscale); } break; case FN_GetMinMax: { size32_t keybuffsize; void *keybuff; size32_t avrecsize; rowcount_t ret = slave.GetMinMax(keybuffsize,keybuff,avrecsize); serializeblk(mbout,keybuffsize,keybuff).append(avrecsize).append(ret); free(keybuff); } break; case FN_GetMultiMidPointStart: { replydone = true; comm->reply(mbout); size32_t lkeybuffsize; void * lkeybuff; size32_t hkeybuffsize; void * hkeybuff; deserializeblk(mb,lkeybuffsize,lkeybuff); deserializeblk(mb,hkeybuffsize,hkeybuff); slave.GetMultiMidPointStart(lkeybuffsize,lkeybuff,hkeybuffsize,hkeybuff); free(lkeybuff); free(hkeybuff); } break; case FN_MultiBinChopStop: { unsigned num; mb.read(num); void *out = mbout.reserveTruncate(num*sizeof(rowcount_t)); slave.MultiBinChopStop(num,(rowcount_t *)out); } break; case FN_GetMultiMidPointStop: { size32_t mkeybuffsize=0; void * mkeybuff = NULL; slave.GetMultiMidPointStop(mkeybuffsize,mkeybuff); serializeblk(mbout,mkeybuffsize,mkeybuff); free(mkeybuff); } break; case FN_MultiBinChopStart: { replydone = true; comm->reply(mbout); size32_t keybuffsize; void * keybuff; deserializeblk(mb,keybuffsize,keybuff); byte cmpfn; mb.read(cmpfn); slave.MultiBinChopStart(keybuffsize,(const byte *)keybuff,cmpfn); free(keybuff); } break; case FN_MultiBinChop: { size32_t keybuffsize; void * keybuff; deserializeblk(mb,keybuffsize,keybuff); unsigned num; byte cmpfn; mb.read(num).read(cmpfn); void *out = mbout.reserveTruncate(num*sizeof(rowcount_t)); slave.MultiBinChop(keybuffsize,(const byte *)keybuff,num,(rowcount_t *)out,cmpfn); free(keybuff); } break; case FN_OverflowAdjustMapStart: { replydone = true; comm->reply(mbout); unsigned mapsize; mb.read(mapsize); const void * map = mb.readDirect(mapsize*sizeof(rowcount_t)); size32_t keybuffsize; void * keybuff; deserializeblk(mb,keybuffsize,keybuff); byte cmpfn; mb.read(cmpfn); bool useaux; mb.read(useaux); slave.OverflowAdjustMapStart(mapsize,(rowcount_t *)map,keybuffsize,(const byte *)keybuff,cmpfn,useaux); free(keybuff); } break; case FN_OverflowAdjustMapStop: { unsigned mapsize; mb.read(mapsize); rowcount_t ret=0; size32_t retofs = mbout.length(); mbout.append(ret); void *map=mbout.reserveTruncate(mapsize*sizeof(rowcount_t)); ret = slave.OverflowAdjustMapStop(mapsize,(rowcount_t *)map); // could avoid copy here if passed mb mbout.writeDirect(retofs,sizeof(ret),&ret); } break; case FN_MultiMerge: { replydone = true; comm->reply(mbout); unsigned mapsize; mb.read(mapsize); const void *map = mb.readDirect(mapsize*sizeof(rowcount_t)); unsigned num; mb.read(num); SocketEndpointArray epa; for (unsigned i=0;i<num;i++) { SocketEndpoint ep; ep.deserialize(mb); epa.append(ep); } slave.MultiMerge(mapsize,(rowcount_t *)map,num,epa.getArray()); } break; case FN_MultiMergeBetween: { replydone = true; comm->reply(mbout); unsigned mapsize; mb.read(mapsize); const void *map = mb.readDirect(mapsize*sizeof(rowcount_t)); const void *mapupper = mb.readDirect(mapsize*sizeof(rowcount_t)); unsigned num; mb.read(num); SocketEndpointArray epa; for (unsigned i=0;i<num;i++) { SocketEndpoint ep; ep.deserialize(mb); epa.append(ep); } slave.MultiMergeBetween(mapsize,(rowcount_t *)map,(rowcount_t *)mapupper,num,epa.getArray()); } break; case FN_SingleMerge: { replydone = true; comm->reply(mbout); // async slave.SingleMerge(); } break; case FN_FirstRowOfFile: { StringAttr filename; mb.read(filename); size32_t rowbufsize = 0; byte *rowbuf = NULL; bool ret = slave.FirstRowOfFile(filename,rowbufsize,rowbuf); serializeblk(mbout,rowbufsize,rowbuf); free(rowbuf); mbout.append(ret); } break; case FN_GetMultiNthRow: { unsigned numsplits; mb.read(numsplits); size32_t mkeybuffsize = 0; void * mkeybuf = NULL; slave.GetMultiNthRow(numsplits,mkeybuffsize,mkeybuf); serializeblk(mbout,mkeybuffsize,mkeybuf); free(mkeybuf); } break; case FN_StartMiniSort: { replydone = true; rowcount_t totalrows; mb.read(totalrows); comm->reply(mbout); // async slave.StartMiniSort(totalrows); } break; case FN_Close: { replydone = true; comm->reply(mbout); // async slave.Close(); } break; case FN_CloseWait: { slave.CloseWait(); } break; case FN_Disconnect: { comm->reply(mbout); // async replydone = true; slave.Disconnect(); } // fall through return false; default: throw MakeStringException(-1,"unknown function %d",(int)fn); } } catch (IException *e) { EXCLOG(e,"SortSlaveMP::marshall"); if (!replydone) { mbout.clear(); okout = 0; mbout.append(okout); int err = e->errorCode(); mbout.append(err); StringBuffer outs; e->errorMessage(outs); mbout.append(outs.str()); } err.setown(e); } if (!replydone) { #ifdef FULLTRACE StringBuffer tmp1; PROGLOG("<SortSlaveMP::marshall(%d) send %d to %s tag %d",(int)fn, mbout.length(), mbout.getSender().getUrlStr(tmp1).str(),mbout.getReplyTag()); #endif comm->reply(mbout); } if (err.get()) throw err.getClear(); return true; }