void process() { CMessageBuffer msg; unsigned inputs = container.getInputs(); unsigned slaves = container.queryJob().querySlaves(); unsigned s; bool readSome=false, slaveReadSome; IntArray replyTags; for (s=0; s<slaves; s++) replyTags.append(0); while (inputs>1) { inputs--; for (s=0; s<slaves; s++) { rank_t sender; if (!receiveMsg(msg, RANK_ALL, replyTag, &sender)) return; replyTags.replace(msg.getReplyTag(), ((int)sender)-1); msg.read(slaveReadSome); if (slaveReadSome) readSome = true; } msg.clear().append(readSome); for (s=0; s<slaves; s++) { if (!queryJobChannel().queryJobComm().send(msg, ((rank_t) s+1), (mptag_t) replyTags.item(s), LONGTIMEOUT)) throw MakeActivityException(this, 0, "Failed to give result to slave"); } if (readSome) // got some, have told slaves to ignore rest, so finish 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; }