2009-02-20 10:46:42 -05:00
// stragegy.cpp
# include "stdafx.h"
# include "request.h"
# include "../client/connpool.h"
# include "../db/commands.h"
2009-03-25 17:35:38 -04:00
# include "shard.h"
2009-02-20 10:46:42 -05:00
namespace mongo {
2009-02-23 21:47:25 -05:00
// ----- Strategy ------
2009-02-20 10:46:42 -05:00
void Strategy : : doWrite ( int op , Request & r , string server ) {
ScopedDbConnection dbcon ( server ) ;
DBClientBase & _c = dbcon . conn ( ) ;
/* TODO FIX - do not case and call DBClientBase::say() */
DBClientConnection & c = dynamic_cast < DBClientConnection & > ( _c ) ;
c . port ( ) . say ( r . m ( ) ) ;
dbcon . done ( ) ;
}
2009-02-21 23:39:41 -05:00
void Strategy : : doQuery ( Request & r , string server ) {
try {
ScopedDbConnection dbcon ( server ) ;
DBClientBase & _c = dbcon . conn ( ) ;
2009-03-25 17:35:38 -04:00
checkShardVersion ( _c , r . getns ( ) ) ;
2009-04-07 15:19:27 -04:00
2009-02-21 23:39:41 -05:00
// TODO: This will not work with Paired connections. Fix.
DBClientConnection & c = dynamic_cast < DBClientConnection & > ( _c ) ;
Message response ;
bool ok = c . port ( ) . call ( r . m ( ) , response ) ;
2009-04-07 15:19:27 -04:00
{
QueryResult * qr = ( QueryResult * ) response . data ;
if ( qr - > resultFlags ( ) & QueryResult : : ResultFlag_ShardConfigStale ) {
throw StaleConfigException ( ) ;
}
}
2009-02-21 23:39:41 -05:00
uassert ( " mongos: error calling db " , ok ) ;
r . reply ( response ) ;
dbcon . done ( ) ;
}
catch ( AssertionException & e ) {
BSONObjBuilder err ;
err . append ( " $err " , string ( " mongos: " ) + ( e . msg . empty ( ) ? " assertion during query " : e . msg ) ) ;
BSONObj errObj = err . done ( ) ;
replyToQuery ( QueryResult : : ResultFlag_ErrSet , r . p ( ) , r . m ( ) , errObj ) ;
}
}
2009-02-20 13:46:57 -05:00
2009-02-20 10:46:42 -05:00
void Strategy : : insert ( string server , const char * ns , const BSONObj & obj ) {
ScopedDbConnection dbcon ( server ) ;
dbcon - > insert ( ns , obj ) ;
2009-02-20 13:46:57 -05:00
dbcon . done ( ) ;
2009-02-20 10:46:42 -05:00
}
2009-02-23 21:47:25 -05:00
2009-03-30 10:50:10 -04:00
map < DBClientBase * , unsigned long long > checkShardVersionLastSequence ;
2009-03-27 16:55:26 -04:00
void checkShardVersion ( DBClientBase & conn , const string & ns , bool authoritative ) {
2009-03-25 17:35:38 -04:00
// TODO: cache, optimize, etc...
DBConfig * conf = grid . getDBConfig ( ns ) ;
if ( ! conf )
return ;
if ( ! conf - > sharded ( ns ) )
return ;
2009-03-27 16:55:26 -04:00
ShardManager * manager = conf - > getShardManager ( ns , authoritative ) ;
2009-03-30 10:50:10 -04:00
unsigned long long & sequenceNumber = checkShardVersionLastSequence [ & conn ] ;
if ( manager - > getSequenceNumber ( ) = = sequenceNumber )
return ;
2009-04-10 10:41:35 -04:00
log ( 2 ) < < " have to set shard version for conn: " < < & conn < < " ns: " < < ns < < " my last seq: " < < sequenceNumber < < " current: " < < manager - > getSequenceNumber ( ) < < endl ;
2009-03-30 10:50:10 -04:00
ServerShardVersion version = manager - > getVersion ( conn . getServerAddress ( ) ) ;
2009-03-27 16:55:26 -04:00
BSONObj result ;
if ( setShardVersion ( conn , ns , version , authoritative , result ) ) {
2009-03-30 10:50:10 -04:00
// success!
sequenceNumber = manager - > getSequenceNumber ( ) ;
2009-03-27 16:55:26 -04:00
return ;
}
log ( 1 ) < < " setShardVersion failed! \n " < < result < < endl ;
if ( result . getBoolField ( " need_authoritative " ) )
massert ( " need_authoritative set but in authoritative mode already " , ! authoritative ) ;
if ( ! authoritative ) {
checkShardVersion ( conn , ns , 1 ) ;
return ;
}
log ( 1 ) < < " setShardVersion failed: " < < result < < endl ;
massert ( " setShardVersion failed! " , 0 ) ;
2009-03-25 17:35:38 -04:00
}
2009-03-27 16:55:26 -04:00
bool setShardVersion ( DBClientBase & conn , const string & ns , ServerShardVersion version , bool authoritative , BSONObj & result ) {
2009-03-25 17:35:38 -04:00
2009-03-27 16:55:26 -04:00
BSONObjBuilder cmdBuilder ;
cmdBuilder . append ( " setShardVersion " , ns . c_str ( ) ) ;
cmdBuilder . append ( " configdb " , configServer . modelServer ( ) ) ;
cmdBuilder . appendTimestamp ( " version " , version ) ;
if ( authoritative )
cmdBuilder . appendBool ( " authoritative " , 1 ) ;
BSONObj cmd = cmdBuilder . obj ( ) ;
2009-03-30 09:48:15 -04:00
log ( 1 ) < < " setShardVersion " < < conn . getServerAddress ( ) < < " " < < ns < < " " < < cmd < < " " < < & conn < < endl ;
2009-03-27 16:55:26 -04:00
return conn . runCommand ( " admin " , cmd , result ) ;
}
2009-04-03 14:21:00 -04:00
bool lockNamespaceOnServer ( const string & server , const string & ns ) {
ScopedDbConnection conn ( server ) ;
bool res = lockNamespaceOnServer ( conn . conn ( ) , ns ) ;
conn . done ( ) ;
return res ;
}
bool lockNamespaceOnServer ( DBClientBase & conn , const string & ns ) {
BSONObj lockResult ;
return setShardVersion ( conn , ns , grid . getNextOpTime ( ) , true , lockResult ) ;
}
2009-02-20 10:46:42 -05:00
}