-
Notifications
You must be signed in to change notification settings - Fork 44
/
rsm_client.h
142 lines (125 loc) · 3.72 KB
/
rsm_client.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef rsm_client_h
#define rsm_client_h
#include "rpc.h"
#include "rsm_protocol.h"
#include <string>
#include <vector>
//
// rsm client interface.
//
// The client stubs package up an rpc, and then call the invoke procedure
// on the replicated state machine passing the RPC as an argument. This way
// the replicated state machine isn't service specific; any server can use it.
//
class rsm_client {
protected:
std::string primary;
std::vector<std::string> known_mems;
pthread_mutex_t rsm_client_mutex;
void primary_failure();
bool init_members();
public:
rsm_client(std::string dst);
rsm_protocol::status invoke(int proc, std::string req, std::string &rep);
template<class R, class A1>
int call(unsigned int proc, const A1 & a1, R &r);
template<class R, class A1, class A2>
int call(unsigned int proc, const A1 & a1, const A2 & a2, R &r);
template<class R, class A1, class A2, class A3>
int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
R &r);
template<class R, class A1, class A2, class A3, class A4>
int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
const A4 & a4, R &r);
template<class R, class A1, class A2, class A3, class A4, class A5>
int call(unsigned int proc, const A1 & a1, const A2 & a2, const A3 & a3,
const A4 & a4, const A5 & a5, R &r);
private:
template<class R> int call_m(unsigned int proc, marshall &req, R &r);
};
template<class R> int
rsm_client::call_m(unsigned int proc, marshall &req, R &r)
{
std::string rep;
std::string res;
int intret = invoke(proc, req.str(), rep);
VERIFY( intret == rsm_client_protocol::OK );
unmarshall u(rep);
u >> intret;
if (intret < 0) return intret;
u >> res;
if (!u.okdone()) {
fprintf(stderr, "rsm_client::call_m: failed to unmarshall the reply.\n"
"You probably forgot to set the reply string in "
"rsm::client_invoke, or you may call RPC 0x%x with wrong return "
"type\n", proc);
VERIFY(0);
return rpc_const::unmarshal_reply_failure;
}
unmarshall u1(res);
u1 >> r;
if(!u1.okdone()) {
fprintf(stderr, "rsm_client::call_m: failed to unmarshall the reply.\n"
"You are probably calling RPC 0x%x with wrong return "
"type.\n", proc);
VERIFY(0);
return rpc_const::unmarshal_reply_failure;
}
return intret;
}
template<class R, class A1> int
rsm_client::call(unsigned int proc, const A1 & a1, R & r)
{
marshall m;
m << a1;
return call_m(proc, m, r);
}
template<class R, class A1, class A2> int
rsm_client::call(unsigned int proc, const A1 & a1, const A2 & a2, R & r)
{
marshall m;
m << a1;
m << a2;
return call_m(proc, m, r);
}
template<class R, class A1, class A2, class A3> int
rsm_client::call(unsigned int proc, const A1 & a1,
const A2 & a2, const A3 & a3, R & r)
{
marshall m;
std::string rep;
std::string res;
m << a1;
m << a2;
m << a3;
return call_m(proc, m, r);
}
template<class R, class A1, class A2, class A3, class A4> int
rsm_client::call(unsigned int proc, const A1 & a1,
const A2 & a2, const A3 & a3, const A4 & a4, R & r)
{
marshall m;
std::string rep;
std::string res;
m << a1;
m << a2;
m << a3;
m << a4;
return call_m(proc, m, r);
}
template<class R, class A1, class A2, class A3, class A4, class A5> int
rsm_client::call(unsigned int proc, const A1 & a1,
const A2 & a2, const A3 & a3, const A4 & a4, const A5 & a5,
R & r)
{
marshall m;
std::string rep;
std::string res;
m << a1;
m << a2;
m << a3;
m << a4;
m << a5;
return call_m(proc, m, r);
}
#endif