📄 ft_client.cpp
字号:
// FT_Client.cpp,v 1.2 2003/12/22 01:44:38 wilson_d Exp
#include "FT_TestReplicaC.h"
#include <ace/Vector_T.h>
#include <ace/SString.h>
#include <ace/Get_Opt.h>
#include <iostream>
#include <fstream>
class FTClientMain
{
typedef ACE_Vector<ACE_CString> StringVec;
public:
///////////////////////////
// construction/destruction
FTClientMain ();
~FTClientMain ();
/////////////////
// initialization
int parse_args (int argc, char *argv[]);
////////////
// execution
int run ();
/////////////////
// implementation
private:
void usage (ostream & out)const;
void commandUsage (ostream & out);
int pass (
long & counter, // inout
int & more, // out
ACE_CString & command, // inout
int retry // in
);
int next_replica (ACE_ENV_SINGLE_ARG_DECL);
////////////////////
// forbidden methods
private:
FTClientMain (const FTClientMain & rhs);
FTClientMain & operator = (const FTClientMain & rhs);
////////////////
// Data members
private:
CORBA::ORB_var orb_;
int argc_;
char ** argv_;
const char * inFileName_;
std::ifstream inFile_;
std::istream *commandIn_;
enum Verbosity{
SILENT,
QUIET,
NORMAL,
NOISY,
LOUD}
verbose_;
StringVec replica_iors_;
size_t replica_pos_;
const char * replica_name_;
FT_TEST::TestReplica_var replica_;
};
FTClientMain::FTClientMain ()
: commandIn_(&std::cin)
, verbose_(NORMAL)
, replica_pos_(0)
, replica_name_("none")
{
}
FTClientMain::~FTClientMain ()
{
if (this->inFile_.is_open())
{
this->inFile_.close();
}
}
void FTClientMain::commandUsage(ostream & out)
{
out
<< "Each command must be at the beginning of a separate line." << std::endl
<< "Everything after the command (and operand if any) is ignored." << std::endl
<< "Valid commands are:" << std::endl
<< " Access via method call:" << std::endl
<< " =N set counter to N" << std::endl
<< " cN get counter and compare to N (c stands for \"check\""<< std::endl
<< " +N increment counter by N" << std::endl
<< " -N decrement counter by N" << std::endl
<< " Access as attribute:" << std::endl
<< " >N set attribute to N" << std::endl
<< " < get attribite" << std::endl
<< " Try methods to be used by fault tolerant infrastructure: " << std::endl
<< " ! is_alive" << std::endl
<< " s get_state" << std::endl
<< " S set_state" << std::endl
<< " u get_update" << std::endl
<< " U set_update" << std::endl
<< " Simulate failure:" << std::endl
<< " dN die on condition:" << std::endl
<< " d" << FT_TEST::TestReplica::NOT_YET << " don't die" << std::endl
<< " d" << FT_TEST::TestReplica::RIGHT_NOW << " immediately" << std::endl
<< " d" << FT_TEST::TestReplica::WHILE_IDLE << " while idle" << std::endl
<< " (FT_TestReplica interface)" << std::endl
<< " d" << FT_TEST::TestReplica::BEFORE_STATE_CHANGE << " before state change" << std::endl
<< " d" << FT_TEST::TestReplica::BEFORE_REPLICATION << " after state change, before replication" << std::endl
<< " d" << FT_TEST::TestReplica::BEFORE_REPLY << " after replication, before reply "<< std::endl
<< " (Monitorable interface)" << std::endl
<< " d" << FT_TEST::TestReplica::DURING_IS_ALIVE << " during is alive" << std::endl
<< " d" << FT_TEST::TestReplica::DENY_IS_ALIVE << " is_alive returns false" << std::endl
<< " (Updatable interface)" << std::endl
<< " d" << FT_TEST::TestReplica::DURING_GET_UPDATE << " during get update" << std::endl
<< " d" << FT_TEST::TestReplica::BEFORE_SET_UPDATE << " before set update" << std::endl
<< " d" << FT_TEST::TestReplica::AFTER_SET_UPDATE << " after set update" << std::endl
<< " (Checkpointable interface)" << std::endl
<< " d" << FT_TEST::TestReplica::DURING_GET_STATE << " during get state" << std::endl
<< " d" << FT_TEST::TestReplica::BEFORE_SET_STATE << " before set state" << std::endl
<< " d" << FT_TEST::TestReplica::AFTER_SET_STATE << " after set state" << std::endl
<< " Logistics commands:" << std::endl
<< " # ignore this line (comment)." << std::endl
<< " v set verbosity:" << std::endl
<< " 0 don't check counter value." << std::endl
<< " 1 only display counter value mismatch." << std::endl
<< " 2 display counter value after every command (default)." << std::endl
<< " 3 display commands." << std::endl
<< " 4 display method calls." << std::endl
<< " zN sleep N seconds." << std::endl
<< " q quit (end the client, not the replica(s).)" << std::endl
<< " q1 quit (end the client, and shutdown the currently active replica.)" << std::endl
<< " ? help (this message)" << std::endl;
}
int
FTClientMain::parse_args (int argc, char *argv[])
{
this->argc_ = argc;
this->argv_ = argv;
int result = 0;
// note: dfnkx are simple_util options
// include them here so we can detect bad args
ACE_Get_Opt get_opts (argc, argv, "c:f:");
int c;
while (result == 0 && (c = get_opts ()) != -1)
{
switch (c)
{
case 'c':
{
this->inFileName_ = get_opts.opt_arg ();
this->inFile_.open(this->inFileName_);
if(this->inFile_.is_open() && this->inFile_.good())
{
std::cout << "FT Client: Reading commands from " << this->inFileName_ << std::endl;
this->commandIn_ = & this->inFile_;
}
else
{
std::cout << "FT Client: Can't open input file: " << this->inFileName_ << std::endl;
result = -1;
}
break;
}
case 'f':
{
replica_iors_.push_back(get_opts.opt_arg ());
break;
}
default:
case '?':
usage(std::cerr);
result = 1;
}
}
return result;
}
void FTClientMain::usage(ostream & out)const
{
out << "usage"
<< " -c <command file>"
<< " [-f <ior file>]..."
<< std::endl;
}
int FTClientMain::pass (
long & counter,
int & more,
ACE_CString & command,
int retry)
{
int result = 0;
::FT::State_var state;
unsigned long stateValue = 0;
::FT::State_var update;
unsigned long updateValue = 0;
while(more && result == 0 && ! this->commandIn_->eof())
{
if (! retry || command.length () == 0 )
{
char buffer[1000];
this->commandIn_->getline(buffer, sizeof(buffer)-1);
command = buffer;
}
retry = 0;
if (command.length() >0)
{
char op = command[0];
ACE_CString cdr = command.substr(1);
char * junque;
long operand = strtol(cdr.c_str(),&junque, 10);
if (this->verbose_ >= NOISY)
{
std::cout << "FT Client: " << command << std::endl;
}
// turn echo on (based on verbose)
// individual commands can turn it off
int echo = this->verbose_ >= QUIET;
switch(op)
{
case '#':
{
echo = 0;
break;
}
case '=':
{
if (this->verbose_ >= LOUD)
{
std::cout << "FT Client: ->set(" << operand << ");" << std::endl;
}
this->replica_->set(operand ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
counter = operand;
break;
}
case 'c':
{
if (this->verbose_ >= LOUD)
{
std::cout << "FT Client: ->get();" << std::endl;
}
long value = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
if (value == operand)
{
std::cout << "FT Client: Good: Read " << value << " expecting " << operand << std::endl;
counter = operand;
}
else
{
std::cout << "FT Client: Error: Read " << value << " expecting " << operand << std::endl;
}
echo = 0;
break;
}
case '>':
{
if (this->verbose_ >= LOUD)
{
std::cout << "FT Client: ->counter(" << operand << ");" << std::endl;
}
this->replica_->counter(operand ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
counter = operand;
break;
}
case '+':
{
if (this->verbose_ >= LOUD)
{
std::cout << "FT Client: ->increment(" << operand << ");" << std::endl;
}
this->replica_->increment(operand ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
counter += operand;
break;
}
case '-':
{
if (this->verbose_ >= LOUD)
{
std::cout << "FT Client: ->increment(" << -operand << ");" << std::endl;
}
this->replica_->increment(-operand ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
counter -= operand;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -