/* Function : registerCommand * Arguments : command - id to register * Description: register command with given id in daemon core */ void ReplicatorStateMachine::registerCommand(int command) { daemonCore->Register_Command( command, const_cast<char*>( utilToString( command ) ), (CommandHandlercpp) &ReplicatorStateMachine::commandHandler, "commandHandler", this, DAEMON ); }
// sending command to remote replication daemon; specified command function // allows to specify which data is to be sent to the remote daemon void AbstractReplicatorStateMachine::sendCommand( int command, char* daemonSinfulString, CommandFunction function ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand %s to %s\n", utilToString( command ), daemonSinfulString ); Daemon daemon( DT_ANY, daemonSinfulString ); ReliSock socket; // no retries after 'm_connectionTimeout' seconds of unsuccessful connection socket.timeout( m_connectionTimeout ); socket.doNotEnforceMinimalCONNECT_TIMEOUT( ); if( ! socket.connect( daemonSinfulString, 0, false ) ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to connect to %s\n", daemonSinfulString ); socket.close( ); return ; } // General actions for any command sending if( ! daemon.startCommand( command, &socket, m_connectionTimeout ) ) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "cannot start command %s to %s\n", utilToString( command ), daemonSinfulString ); socket.close( ); return ; } char const* sinfulString = daemonCore->InfoCommandSinfulString(); if(! socket.put( sinfulString )/* || ! socket.end_of_message( )*/) { dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to code the local sinful string or eom%s\n", sinfulString ); socket.close( ); return ; } else { dprintf( D_FULLDEBUG, "AbstractReplicatorStateMachine::sendCommand " "local sinful string coded successfully\n" ); } // End of General actions for any command sending // Command-specific actions if( ! ((*this).*(function))( socket ) ) { socket.close( ); return ; } // End of Command-specific actions if( ! socket.end_of_message( ) ) { socket.close( ); dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "unable to code the end of message\n" ); return ; } socket.close( ); dprintf( D_ALWAYS, "AbstractReplicatorStateMachine::sendCommand " "%s command sent to %s successfully\n", utilToString( command ), daemonSinfulString ); }
/* Function : commandHandler * Arguments : command - command to handle request * stream - socket, through which the data for the command arrived * Description: handles various commands sent to this replication daemon */ void ReplicatorStateMachine::commandHandler( int command, Stream* stream ) { char* daemonSinfulString = 0; stream->decode( ); if( ! stream->code( daemonSinfulString ) /*|| ! stream->end_of_message( )*/ ) { dprintf( D_NETWORK, "ReplicatorStateMachine::commandHandler " "cannot read remote daemon sinful string for %s\n", utilToString( command ) ); free( daemonSinfulString ); return; } dprintf( /*D_COMMAND*/ D_FULLDEBUG, "ReplicatorStateMachine::commandHandler received " "command %s from %s\n", utilToString(command), daemonSinfulString ); switch( command ) { case REPLICATION_LEADER_VERSION: onLeaderVersion( stream ); break; case REPLICATION_TRANSFER_FILE: onTransferFile( daemonSinfulString ); break; case REPLICATION_SOLICIT_VERSION: onSolicitVersion( daemonSinfulString ); break; case REPLICATION_SOLICIT_VERSION_REPLY: onSolicitVersionReply( stream ); break; case REPLICATION_NEWLY_JOINED_VERSION: onNewlyJoinedVersion( stream ); break; case REPLICATION_GIVING_UP_VERSION: onGivingUpVersion( stream ); break; case HAD_BEFORE_PASSIVE_STATE: beforePassiveStateHandler(); break; case HAD_AFTER_ELECTION_STATE: afterElectionStateHandler(); break; case HAD_AFTER_LEADER_STATE: afterLeaderStateHandler(); break; case HAD_IN_LEADER_STATE: inLeaderStateHandler(); break; } free( daemonSinfulString ); if( ! stream->end_of_message( ) ) { dprintf( D_NETWORK, "ReplicatorStateMachine::commandHandler " "cannot read the end of the message\n" ); } }