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;
        }
    }
Exemple #2
0
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;
}