BufSend & BufReceive: zero size message


#1

Quick question: Can BufSend and a matching BufReceive handle a message of zero size?

Thanks,
-Hamid


#2

Yes that does work.
Cheers.

-Alex Poliakov


#3

Thanks Alex.
What could I be doing wrong in the attached test?
Works when messageSize > 0; fails when messageSize=0.
Tried both 13.6 and 13.11 versions of SciDB (downloads of prebuilt Ubuntu versions from Paradigm4).
Ubuntu version is 12.04.3 running as a VM within VirtualBox version 4.3.2.
Failure message is the generic

[quote]SystemException in file: src/network/BaseConnection.h function: receive line: 294
Error id: scidb::SCIDB_SE_NETWORK::SCIDB_LE_CANT_SEND_RECEIVE
Error description: Network error. Cannot send or receive network messages.[/quote]

-Hamid

//LogicalTest.cpp
#include <query/Operator.h>
namespace scidb
{
class LogicalTest : public LogicalOperator
{
public:
    LogicalTest(const string& logicalName, const string& alias):
        LogicalOperator(logicalName, alias)
    { ADD_PARAM_INPUT() }

    ArrayDesc inferSchema(vector< ArrayDesc> schemas, shared_ptr< Query> query)
    {
        ArrayDesc const& inputSchema = schemas[0];
        return inputSchema;
    }
};
REGISTER_LOGICAL_OPERATOR_FACTORY(LogicalTest,"myTest");
}
//PhysicalTest.cpp
#include <query/Operator.h>
#include <query/Network.h>
namespace scidb
{
static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("scidb.testUDO"));
class PhysicalTest : public PhysicalOperator
{
public:
    PhysicalTest(string const& logicalName,
                           string const& physicalName,
                           Parameters const& parameters,
                           ArrayDesc const& schema):
        PhysicalOperator(logicalName, physicalName, parameters, schema)
    {}

    shared_ptr<SharedBuffer> marshall(size_t messageSize)
    {
        shared_ptr <SharedBuffer> result (new MemoryBuffer(NULL, messageSize));
        return result;
    }
    shared_ptr< Array> execute(vector< shared_ptr< Array> >& inputArrays, shared_ptr<Query> query)
    {
        if (query->getInstanceID() != 0)
        {
            shared_ptr<SharedBuffer> buf = marshall(1);
            BufSend(0, buf, query);
            LOG4CXX_DEBUG(logger, "Size sent "<<buf->getSize());
        }
        else
        {
            for (InstanceID i = 1; i<query->getInstancesCount(); ++i)
            {
                shared_ptr<SharedBuffer> buf = BufReceive(i, query);
                LOG4CXX_DEBUG(logger, "Size received "<<i<<" "<<buf->getSize());
            }
        }
        shared_ptr<Array> outputArray(new MemArray(_schema, query));
        return outputArray;
    }
};
REGISTER_PHYSICAL_OPERATOR_FACTORY(PhysicalTest, "myTest", "PhysicalTest");
}
#Makefile
BOOST_LOCATION=/usr/include
SCIDB_SOURCE_DIR=/opt/scidb/13.6

CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3  -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(SCIDB_SOURCE_DIR)\"" -I"$(SCIDB_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(SCIDB_SOURCE_DIR)/lib" -shared -Wl,-soname,libmyTest.so -L. -lm

all: $(OBJS) LogicalTest.cpp.o PhysicalTest.cpp.o
        @if test ! -d "$(SCIDB_SOURCE_DIR)"; then echo  "Error. Try:\n\nmake SCIDB_SOURCE_DIR=<PATH TO SCIDB TRUNK>"; exit 1; fi 
        $(CXX) $(CFLAGS) $(INC) -o libmyTest.so \
                            LogicalTest.cpp.o \
                            PhysicalTest.cpp.o \
                            $(LIBS)

LogicalTest.cpp.o:LogicalTest.cpp
        $(CXX) $(CFLAGS) $(INC) -o LogicalTest.cpp.o -c LogicalTest.cpp
PhysicalTest.cpp.o:PhysicalTest.cpp
        $(CXX) $(CFLAGS) $(INC) -o PhysicalTest.cpp.o -c PhysicalTest.cpp

clean:
        rm -f *.o *.so

#4

Hi Hamid,

You can send an empty message by BufSend’ing a null pointer like this:

        BufSend(instance,shared_ptr<SharedBuffer>(),query);    // ...send null ptr

and can detect receipt of such an empty message like this:

        if (boost::shared_ptr<SharedBuffer> p = BufReceive(instance,query)) {
            // fine, use p here
        }
        else
        {
            // recieved an empty message
        }

Hope this helps,

Jonathon


#5

Jonathon,
Thanks. Yes it works.

-Hamid