int handle_bigrep(string &r, const size_t a);
};
+namespace srv_protocol {
+ using status = rpc_protocol::status;
+ REMOTE_PROCEDURE_BASE(0);
+ REMOTE_PROCEDURE(22, _22, (string &, string, string));
+ REMOTE_PROCEDURE(23, fast, (int &, int));
+ REMOTE_PROCEDURE(24, slow, (int &, int));
+ REMOTE_PROCEDURE(25, bigrep, (string &, size_t));
+};
+
// a handler. a and b are arguments, r is the result.
// there can be multiple arguments but only one result.
// the caller also gets to see the int return value
// rpcs::reg() decides how to unmarshall by looking
// at these argument types, so this function definition
// does what a .x file does in SunRPC.
-int
-srv::handle_22(string &r, const string a, string b)
-{
+int srv::handle_22(string &r, const string a, string b) {
r = a + b;
return 0;
}
-int
-srv::handle_fast(int &r, const int a)
-{
+int srv::handle_fast(int &r, const int a) {
r = a + 1;
return 0;
}
-int
-srv::handle_slow(int &r, const int a)
-{
+int srv::handle_slow(int &r, const int a) {
usleep(random() % 500);
r = a + 2;
return 0;
}
-int
-srv::handle_bigrep(string &r, const size_t len)
-{
+int srv::handle_bigrep(string &r, const size_t len) {
r = string((size_t)len, 'x');
return 0;
}
srv service;
-void startserver()
-{
+void startserver() {
server = new rpcs(port);
- server->reg(22, &srv::handle_22, &service);
- server->reg(23, &srv::handle_fast, &service);
- server->reg(24, &srv::handle_slow, &service);
- server->reg(25, &srv::handle_bigrep, &service);
+ server->reg(srv_protocol::_22, &srv::handle_22, &service);
+ server->reg(srv_protocol::fast, &srv::handle_fast, &service);
+ server->reg(srv_protocol::slow, &srv::handle_slow, &service);
+ server->reg(srv_protocol::bigrep, &srv::handle_bigrep, &service);
server->start();
}
-void
-testmarshall()
-{
+void testmarshall() {
marshall m;
- request_header rh{1,2,3,4,5};
+ rpc_protocol::request_header rh{1,2,3,4,5};
m.pack_header(rh);
- VERIFY(((string)m).size()==RPC_HEADER_SZ);
+ VERIFY(((string)m).size()==rpc_protocol::RPC_HEADER_SZ);
int i = 12345;
unsigned long long l = 1223344455L;
string s = "hallo....";
m << s;
string b = m;
- VERIFY(b.size() == RPC_HEADER_SZ+sizeof(i)+sizeof(l)+s.size()+sizeof(int));
+ VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+s.size()+sizeof(int));
unmarshall un(b, true);
- request_header rh1;
+ rpc_protocol::request_header rh1;
un.unpack_header(rh1);
VERIFY(memcmp(&rh,&rh1,sizeof(rh))==0);
int i1;
VERIFY(i1==i && l1==l && s1==s);
}
-void
-client1(size_t cl)
-{
+void client1(size_t cl) {
// test concurrency.
size_t which_cl = cl % NUM_CL;
for(int i = 0; i < 100; i++){
- int arg = (random() % 2000);
+ unsigned long arg = (random() % 2000);
string rep;
- int ret = clients[which_cl]->call(25, rep, arg);
+ int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg);
VERIFY(ret == 0);
- if ((int)rep.size()!=arg)
+ if ((unsigned long)rep.size()!=arg)
cout << "repsize wrong " << rep.size() << "!=" << arg << endl;
- VERIFY((int)rep.size() == arg);
+ VERIFY((unsigned long)rep.size() == arg);
}
// test rpc replies coming back not in the order of
auto start = steady_clock::now();
- int ret = clients[which_cl]->call(which ? 23 : 24, rep, arg);
+ int ret = clients[which_cl]->call(which ? srv_protocol::fast : srv_protocol::slow, rep, arg);
auto end = steady_clock::now();
auto diff = duration_cast<milliseconds>(end - start).count();
if (ret != 0)
}
}
-void
-client2(size_t cl)
-{
+void client2(size_t cl) {
size_t which_cl = cl % NUM_CL;
time_t t1;
time(&t1);
while(time(0) - t1 < 10){
- int arg = (random() % 2000);
+ unsigned long arg = (random() % 2000);
string rep;
- int ret = clients[which_cl]->call(25, rep, arg);
- if ((int)rep.size()!=arg)
+ int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg);
+ if ((unsigned long)rep.size()!=arg)
cout << "ask for " << arg << " reply got " << rep.size() << " ret " << ret << endl;
- VERIFY((int)rep.size() == arg);
+ VERIFY((unsigned long)rep.size() == arg);
}
}
-void
-client3(void *xx)
-{
+void client3(void *xx) {
rpcc *c = (rpcc *) xx;
for(int i = 0; i < 4; i++){
int rep = 0;
- int ret = c->call_timeout(24, milliseconds(300), rep, i);
- VERIFY(ret == rpc_const::timeout_failure || rep == i+2);
+ int ret = c->call_timeout(srv_protocol::slow, milliseconds(300), rep, i);
+ VERIFY(ret == rpc_protocol::timeout_failure || rep == i+2);
}
}
-
-void
-simple_tests(rpcc *c)
-{
+void simple_tests(rpcc *c) {
cout << "simple_tests" << endl;
// an RPC call to procedure #22.
// rpcc::call() looks at the argument types to decide how
// to marshall the RPC call packet, and how to unmarshall
// the reply packet.
string rep;
- int intret = c->call(22, rep, (string)"hello", (string)" goodbye");
+ int intret = c->call(srv_protocol::_22, rep, (string)"hello", (string)" goodbye");
VERIFY(intret == 0); // this is what handle_22 returns
VERIFY(rep == "hello goodbye");
cout << " -- string concat RPC .. ok" << endl;
// small request, big reply (perhaps req via UDP, reply via TCP)
- intret = c->call_timeout(25, milliseconds(20000), rep, 70000);
+ intret = c->call_timeout(srv_protocol::bigrep, milliseconds(20000), rep, 70000ul);
VERIFY(intret == 0);
VERIFY(rep.size() == 70000);
cout << " -- small request, big reply .. ok" << endl;
// specify a timeout value to an RPC that should succeed (udp)
int xx = 0;
- intret = c->call_timeout(23, milliseconds(300), xx, 77);
+ intret = c->call_timeout(srv_protocol::fast, milliseconds(300), xx, 77);
VERIFY(intret == 0 && xx == 78);
cout << " -- no spurious timeout .. ok" << endl;
{
string arg(1000, 'x');
string rep2;
- c->call_timeout(22, milliseconds(300), rep2, arg, (string)"x");
+ c->call_timeout(srv_protocol::_22, milliseconds(300), rep2, arg, (string)"x");
VERIFY(rep2.size() == 1001);
cout << " -- no spurious timeout .. ok" << endl;
}
// huge RPC
string big(1000000, 'x');
- intret = c->call(22, rep, big, (string)"z");
+ intret = c->call(srv_protocol::_22, rep, big, (string)"z");
VERIFY(rep.size() == 1000001);
cout << " -- huge 1M rpc request .. ok" << endl;
cout << "simple_tests OK" << endl;
}
-void
-concurrent_test(size_t nt)
-{
+void concurrent_test(size_t nt) {
// create threads that make lots of calls in parallel,
// to test thread synchronization for concurrent calls
// and dispatches.
cout << " OK" << endl;
}
-void
-lossy_test()
-{
+void lossy_test() {
cout << "start lossy_test ...";
VERIFY(setenv("RPC_LOSSY", "5", 1) == 0);
VERIFY(setenv("RPC_LOSSY", "0", 1) == 0);
}
-void
-failure_test()
-{
+void failure_test() {
rpcc *client1;
rpcc *client = clients[0];
startserver();
string rep;
- int intret = client->call(22, rep, (string)"hello", (string)" goodbye");
- VERIFY(intret == rpc_const::oldsrv_failure);
+ int intret = client->call(srv_protocol::_22, rep, (string)"hello", (string)" goodbye");
+ VERIFY(intret == rpc_protocol::oldsrv_failure);
cout << " -- call recovered server with old client .. failed ok" << endl;
delete client;
VERIFY (client->bind() >= 0);
VERIFY (client->bind() < 0);
- intret = client->call(22, rep, (string)"hello", (string)" goodbye");
+ intret = client->call(srv_protocol::_22, rep, (string)"hello", (string)" goodbye");
VERIFY(intret == 0);
VERIFY(rep == "hello goodbye");
cout << "failure_test OK" << endl;
}
-int
-main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
testmarshall();
if (isserver) {
- cout << "starting server on port " << port << " RPC_HEADER_SZ " << (int)RPC_HEADER_SZ << endl;
+ cout << "starting server on port " << port << " RPC_HEADER_SZ " << (int)rpc_protocol::RPC_HEADER_SZ << endl;
startserver();
}
exit(0);
}
- while (1) {
+ while (1)
usleep(100000);
- }
}