예제 #1
0
uint128_t VersionedSlaveCM::sync( const uint128_t& v )
{
#if 0
    LBLOG( LOG_OBJECTS ) << "sync to v" << v << ", id " << _object->getID()
                         << "." << _object->getInstanceID() << std::endl;
#endif
    if( _version == v )
        return _version;

    if( v == VERSION_HEAD )
    {
        _syncToHead();
        return _version;
    }

    const uint128_t version = ( v == VERSION_NEXT ) ? _version + 1 : v;
    LBASSERTINFO( version.high() == 0, "Not a master version: " << version )
    LBASSERTINFO( _version <= version,
                  "can't sync to older version of object " << 
                  lunchbox::className( _object ) << " " << _object->getID() <<
                  " (" << _version << ", " << version <<")" );

    while( _version < version )
        _unpackOneVersion( _queuedVersions.pop( ));

    LocalNodePtr node = _object->getLocalNode();
    if( node.isValid( ))
        node->flushCommands();

    return _version;
}
예제 #2
0
//---------------------------------------------------------------------------
// command handlers
//---------------------------------------------------------------------------
bool UnbufferedMasterCM::_cmdCommit( Command& command )
{
    EQ_TS_THREAD( _cmdThread );
    LocalNodePtr localNode = _object->getLocalNode();
    const ObjectCommitPacket* packet = command.get<ObjectCommitPacket>();
#if 0
    EQLOG( LOG_OBJECTS ) << "commit v" << _version << " " << command
                         << std::endl;
#endif
    if( _slaves.empty( ))
    {
        localNode->serveRequest( packet->requestID, _version );
        return true;
    }

    ObjectDeltaDataOStream os( this );
    os.enableCommit( _version + 1, _slaves );
    _object->pack( os );
    os.disable();

    if( os.hasSentData( ))
    {
        ++_version;
        EQASSERT( _version != VERSION_NONE );
#if 0
        EQLOG( LOG_OBJECTS ) << "Committed v" << _version << ", id " 
                             << _object->getID() << std::endl;
#endif
    }

    localNode->serveRequest( packet->requestID, _version );
    return true;
}
예제 #3
0
uint128_t MasterCM::commitSync( const uint32_t commitID )
{
    LocalNodePtr localNode = _object->getLocalNode();
    uint128_t version = VERSION_NONE;
    localNode->waitRequest( commitID, version );
    return version;
}
예제 #4
0
void QueueSlave::applyInstanceData( co::DataIStream& is )
{
    NodeID masterNodeID;
    is >> _impl->masterInstanceID >> masterNodeID;

    LBASSERT( masterNodeID != 0 );
    LBASSERT( !_impl->master );
    LocalNodePtr localNode = getLocalNode();
    _impl->master = localNode->connect( masterNodeID );
}
예제 #5
0
void QueueSlave::applyInstanceData( co::DataIStream& is )
{
    uint128_t masterNodeID;
    is >> _impl->masterInstanceID >> masterNodeID;

    EQASSERT( masterNodeID != NodeID::ZERO );
    EQASSERT( !_impl->master );
    LocalNodePtr localNode = getLocalNode();
    _impl->master = localNode->connect( masterNodeID );
}
예제 #6
0
uint32_t MasterCM::commitNB( const uint32_t incarnation )
{
    LocalNodePtr localNode = _object->getLocalNode();
    ObjectCommitPacket packet;
    packet.instanceID = _object->_instanceID;
    packet.requestID  = localNode->registerRequest();
    packet.incarnation = incarnation;

    _object->send( localNode, packet );
    return packet.requestID;
}
예제 #7
0
void VersionedSlaveCM::_syncToHead()
{
    if( _queuedVersions.isEmpty( ))
        return;

    ObjectDataIStream* is = 0;
    while( _queuedVersions.tryPop( is ))
        _unpackOneVersion( is );

    LocalNodePtr localNode = _object->getLocalNode();
    if( localNode.isValid( ))
        localNode->flushCommands();
}
예제 #8
0
CustomOCommand::CustomOCommand(LocalNodePtr localNode,
                               const uint128_t& commandID)
    : OCommand(localNode.get(), localNode, CMD_NODE_COMMAND, COMMANDTYPE_NODE)
    , _impl(new detail::CustomOCommand(commandID))
{
    _init();
}
예제 #9
0
ObjectDataICommand ObjectDataOCommand::_getCommand( LocalNodePtr node )
{
    lunchbox::Bufferb& outBuffer = getBuffer();
    uint8_t* bytes = outBuffer.getData();
    reinterpret_cast< uint64_t* >( bytes )[ 0 ] = outBuffer.getSize();

    BufferPtr inBuffer = node->allocBuffer( outBuffer.getSize( ));
    inBuffer->swap( outBuffer );
    return ObjectDataICommand( node, node, inBuffer, false );
}
예제 #10
0
파일: command.cpp 프로젝트: qqdiguo/Collage
int main( int argc, char **argv )
{
    TEST( co::init( argc, argv ) );

    co::ConnectionDescriptionPtr connDesc = new co::ConnectionDescription;

    connDesc->type = co::CONNECTIONTYPE_TCPIP;
    connDesc->setHostname( "localhost" );

    LocalNodePtr server = new LocalNode;
    server->addConnectionDescription( connDesc );
    TEST( server->listen( ));

    co::NodePtr serverProxy = new co::Node;
    serverProxy->addConnectionDescription( connDesc );

    connDesc = new co::ConnectionDescription;
    connDesc->type = co::CONNECTIONTYPE_TCPIP;
    connDesc->setHostname( "localhost" );

    LocalNodePtr client = new LocalNode;
    client->addConnectionDescription( connDesc );
    TEST( client->listen( ));
    TEST( client->connect( serverProxy ));

    lunchbox::Clock clock;
    for( size_t i = 0; i < NCOMMANDS; ++i )
        serverProxy->send( CMD_ASYNC );
    uint32_t request = client->registerRequest();
    serverProxy->send( CMD_SYNC ) << request;
    client->waitRequest( request );
    const float asyncTime = clock.resetTimef();

    for( size_t i = 0; i < NCOMMANDS; ++i )
    {
        request = client->registerRequest();
        serverProxy->send( CMD_SYNC ) << request;
        client->waitRequest( request );
    }
    const float syncTime = clock.resetTimef();

    for( size_t i = 0; i < NCOMMANDS; ++i )
    {
        lunchbox::Request< void > future = client->registerRequest< void >();
        serverProxy->send( CMD_SYNC ) << future;
    }
    const float syncTimeFuture = clock.resetTimef();

    for( size_t i = 0; i < NCOMMANDS; ++i )
    {
        lunchbox::Request< uint32_t > future =
            client->registerRequest< uint32_t >();
        serverProxy->send( CMD_DATA ) << future << payload;
    }
    const float syncTimePayload = clock.resetTimef();

    std::cout << "Async command: " << asyncTime/float(NCOMMANDS)
              << " ms, sync: " << syncTime/float(NCOMMANDS)
              << " ms, using future: " << syncTimeFuture/float(NCOMMANDS+1)
              << " ms, with " << payload.size() << "b payload: "
              << syncTimePayload/float(NCOMMANDS+1) << std::endl;

    TEST( client->disconnect( serverProxy ));
    TEST( client->close( ));
    TEST( server->close( ));

    serverProxy->printHolders( std::cerr );
    TESTINFO( serverProxy->getRefCount() == 1, serverProxy->getRefCount( ));
    TESTINFO( client->getRefCount() == 1, client->getRefCount( ));
    TESTINFO( server->getRefCount() == 1, server->getRefCount( ));

    serverProxy = 0;
    client      = 0;
    server      = 0;

    TEST( co::exit( ));

    return EXIT_SUCCESS;
}