void ObjectStore::unmap( Object* object ) { LBASSERT( object ); if( !object->isAttached( )) // not registered return; const uint128_t& id = object->getID(); LBLOG( LOG_OBJECTS ) << "Unmap " << object << std::endl; object->notifyDetach(); // send unsubscribe to master, master will send detach command. LBASSERT( !object->isMaster( )); LB_TS_NOT_THREAD( _commandThread ); const uint32_t masterInstanceID = object->getMasterInstanceID(); if( masterInstanceID != CO_INSTANCE_INVALID ) { NodePtr master = object->getMasterNode(); LBASSERT( master ) if( master && master->isReachable( )) { lunchbox::Request< void > request = _localNode->registerRequest< void >(); master->send( CMD_NODE_UNSUBSCRIBE_OBJECT ) << id << request << masterInstanceID << object->getInstanceID(); request.wait(); object->notifyDetached(); return; } LBERROR << "Master node for object id " << id << " not connected" << std::endl; }
uint32_t ObjectStore::_startSync( Object* object, NodePtr master, const uint128_t& id, const uint32_t instanceID ) { LB_TS_NOT_THREAD( _receiverThread ); LBLOG( LOG_OBJECTS ) << "Syncing " << lunchbox::className( object ) << " with id " << id << std::endl; LBASSERT( object ); LBASSERTINFO( id.isUUID(), id ); if( !object || !id.isUUID( )) { LBWARN << "Invalid object " << object << " or id " << id << std::endl; return LB_UNDEFINED_UINT32; } if( !master ) master = _localNode->connectObjectMaster( id ); if( !master || !master->isReachable( )) { LBWARN << "Mapping of object " << id << " failed, invalid master node" << std::endl; return LB_UNDEFINED_UINT32; } const uint32_t request = _localNode->registerRequest( new ObjectDataIStream ); uint128_t minCachedVersion = VERSION_HEAD; uint128_t maxCachedVersion = VERSION_NONE; uint32_t cacheInstanceID = 0; bool useCache = _checkInstanceCache( id, minCachedVersion, maxCachedVersion, cacheInstanceID ); if( useCache ) { switch( instanceID ) { case CO_INSTANCE_ALL: break; default: if( instanceID == cacheInstanceID ) break; useCache = false; LBCHECK( _instanceCache->release( id, 1 )); break; } } // Use stream expected by MasterCMCommand master->send( CMD_NODE_SYNC_OBJECT ) << VERSION_NEWEST << minCachedVersion << maxCachedVersion << id << uint64_t(0) /* maxVersions */ << request << instanceID << cacheInstanceID << useCache; return request; }
void ObjectStore::detach( Object* object ) { LBASSERT( object ); LB_TS_NOT_THREAD( _receiverThread ); lunchbox::Request< void > request = _localNode->registerRequest< void >(); _localNode->send( CMD_NODE_DETACH_OBJECT ) << object->getID() << object->getInstanceID() << request; }
bool Config::_cmdCreateReply( co::ICommand& cmd ) { co::ObjectICommand command( cmd ); LB_TS_THREAD( _cmdThread ); LB_TS_NOT_THREAD( _mainThread ); getLocalNode()->serveRequest( command.read< uint32_t >( )); return true; }
//--------------------------------------------------------------------------- // object mapping //--------------------------------------------------------------------------- void ObjectStore::attach( Object* object, const uint128_t& id, const uint32_t instanceID ) { LBASSERT( object ); LB_TS_NOT_THREAD( _receiverThread ); lunchbox::Request< void > request = _localNode->registerRequest< void >( object ); _localNode->send( CMD_NODE_ATTACH_OBJECT ) << id << instanceID << request; }
uint32_t ObjectStore::mapNB( Object* object, const uint128_t& id, const uint128_t& version, NodePtr master ) { LB_TS_NOT_THREAD( _receiverThread ); LBLOG( LOG_OBJECTS ) << "Mapping " << lunchbox::className( object ) << " to id " << id << " version " << version << std::endl; LBASSERT( object ); LBASSERTINFO( id.isUUID(), id ); if( !master ) master = _localNode->connectObjectMaster( id ); if( !master || !master->isReachable( )) { LBWARN << "Mapping of object " << id << " failed, invalid master node" << std::endl; return LB_UNDEFINED_UINT32; } if( !object || !id.isUUID( )) { LBWARN << "Invalid object " << object << " or id " << id << std::endl; return LB_UNDEFINED_UINT32; } const bool isAttached = object->isAttached(); const bool isMaster = object->isMaster(); LBASSERTINFO( !isAttached, *object ); LBASSERT( !isMaster ) ; if( isAttached || isMaster ) { LBWARN << "Invalid object state: attached " << isAttached << " master " << isMaster << std::endl; return LB_UNDEFINED_UINT32; } const uint32_t request = _localNode->registerRequest( object ); uint128_t minCachedVersion = VERSION_HEAD; uint128_t maxCachedVersion = VERSION_NONE; uint32_t masterInstanceID = 0; const bool useCache = _checkInstanceCache( id, minCachedVersion, maxCachedVersion, masterInstanceID ); object->notifyAttach(); master->send( CMD_NODE_MAP_OBJECT ) << version << minCachedVersion << maxCachedVersion << id << object->getMaxVersions() << request << _genNextID( _instanceIDs ) << masterInstanceID << useCache; return request; }
//--------------------------------------------------------------------------- // identifier master node mapping //--------------------------------------------------------------------------- NodeID ObjectStore::findMasterNodeID( const uint128_t& identifier ) { LB_TS_NOT_THREAD( _commandThread ); // OPT: look up locally first? Nodes nodes; _localNode->getNodes( nodes ); // OPT: send to multiple nodes at once? for( NodesIter i = nodes.begin(); i != nodes.end(); ++i ) { NodePtr node = *i; lunchbox::Request< NodeID > request = _localNode->registerRequest< NodeID >(); LBLOG( LOG_OBJECTS ) << "Finding " << identifier << " on " << node << " req " << request.getID() << std::endl; node->send( CMD_NODE_FIND_MASTER_NODE_ID ) << identifier << request; try { const NodeID& masterNodeID = request.wait( Global::getTimeout( )); if( masterNodeID != 0 ) { LBLOG( LOG_OBJECTS ) << "Found " << identifier << " on " << masterNodeID << std::endl; return masterNodeID; } } catch( const lunchbox::FutureTimeout& ) { _localNode->unregisterRequest( request.getID( )); throw; } } return NodeID(); }